VC Resource 관련

리소스 ID충돌을 피하기 위하여 다음과 같은 루틴을 사용하게 된다.

#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE        263
#define _APS_NEXT_COMMAND_VALUE         33249
#define _APS_NEXT_CONTROL_VALUE         1152
#define _APS_NEXT_SYMED_VALUE           104
#endif
#endif

각각의 심볼의 의미는 다음과 같다.

_APS_NEXT_RESOURCE_VALUE is the next symbol value that will be used for a dialog resource, menu resource, and so on. The valid range for resource symbol values is 1 to 0x6FFF.


_APS_NEXT_COMMAND_VALUE is the next symbol value that will be used for a command identification. The valid range for command symbol values is 0x8000 to 0xDFFF.


_APS_NEXT_CONTROL_VALUE is the next symbol value that will be used for a dialog control. The valid range for dialog control symbol values is 8 to 0xDFFF.


_APS_NEXT_SYMED_VALUE is the next symbol value that will be issued when you manually assign a symbol value using the New command in the Symbol Browser.

여러개의 rc파일을 사용시 새로운 rc파일에서 리소스 추가 전에 충돌하지 않는 새로운 시작 ID를 할당한다. 너무 큰 숫자를 할당하게 되면 더이상 사용할 수 있는 리소스가 없어지므로 주의한다.

할당예)
#define _APS_NEXT_RESOURCE_VALUE  2000
#define _APS_NEXT_COMMAND_VALUE   42000
#define _APS_NEXT_CONTROL_VALUE   2000
#define _APS_NEXT_SYMED_VALUE     2000

PCLinuxOS 설치

남는 P3 Dual 컴퓨터에 PCLinuxOS를 설치해 보았다.
한글 지원이 정식으로 안되는것 제외하고는 정말 잘 만들어진 패키지란 느낌이 든다.

윈도우즈의 제어판과 유사한 제어판..
복잡한 설정없이 CD부팅후 로컬 디스크에 자동으로 인스톨~
기능추가시 자동 다운로드 및 설치후 설정
KDE3.X기반의 데스크톱 환경, 독특한 파일 관리자 ( 윈도우즈와 유사 )
여러가지 데스크톱 어플리케이션

일반적으로 사무용으로 사용되는 컴퓨터는 그냥 별다른 설정없이 자동설치후 사용가능할것 같다.

Hooking과 VirtualAlloc을 통한 다른 프로그램의 ListView내용얻어오기

일반적으로 서로 다른 프로그램에서 Message전송만을 통한 Cotrol의 값의 복사가 가능하다. 하지만, 기본컨트롤이 아닌 다른 Cotrol에서 내용을 얻어오고자 할때는 Message와 VirtualAlloc을 이용해야 한다.

기본적인 순서는 다음과 같다.

1. 윈도우 핸들을 얻는다.
2. 차일드 윈도우목록에서 ListView의 핸들을 얻는다.
3. 메세지를 통해서 Item의 숫자를 얻는다.
4. ListView의 프로세스 id를 얻는다.
5. ListView의 프로세스에서 메모리를 할당한다.
6. 할당된 메모리와 Message를 이용하여 Item의 내용을 읽어온다.
7. 할당된 메모리를 해제

 다음의 예제는 어느 회사의 사용자를 검색하여 List에 출력하여 주는 간단한 델파일 프로그램을 후킹하여 사용자정보를 CSV파일로 저장하는 루틴이다.
리스트에 표현되는 정보는 순번,이름,직책,부서명,회사명,보직/담당업무,전화번호,핸드폰,이메일 이며 EnumChildWindows는 CallBack함수를 필요로한다.

HWND hFlatEdit;
HWND hListView;
CString filename;
int lineCount = 1;

BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lPara){


 HWND hEdit = ::FindWindowEx(hwnd,NULL, “TFlatEdit”,””);
 HWND hList = ::FindWindowEx(hwnd,NULL, “TListView”, “”);
 if(hList > 0){
  hListView = hList;
  //TRACE1(“List Handle : %d\n”, hList);
 }


 if(hEdit > 0){
  //TRACE1(“Edit Handle : %d\n”,hEdit);
  hFlatEdit = hEdit;  
 }
 return TRUE;
}

void Save()
{
 HWND hwnd = ::FindWindow(NULL,”사용자검색”);
 CWnd* cwnd = CWnd::FromHandle(hwnd);   
 HINSTANCE hInstance = (HINSTANCE)(::GetWindowLong(hwnd, GWL_HINSTANCE));
 

 if(cwnd == NULL || hInstance==0){
    MessageBox(“사용자 검색창을 열어주세요”,”사용자검색창”,MB_OK);
 } else {
 
  cwnd->SetForegroundWindow();
  ::EnumChildWindows(cwnd->GetSafeHwnd(), EnumChildProc,LPARAM(cwnd));
 
  int count=(int)::SendMessage(hListView, LVM_GETITEMCOUNT, 0, 0);
  int i;
  LVITEM lvi, *_lvi;
  char item[512], subitem1[512],subitem2[512],subitem3[512],subitem4[512],subitem5[512],subitem6[512],subitem7[512],subitem8[512];
  char *_item, *_subitem1,*_subitem2,*_subitem3,*_subitem4,*_subitem5,*_subitem6,*_subitem7,*_subitem8;
  unsigned long pid;
  HANDLE process;


  GetWindowThreadProcessId(hListView, &pid);
  process=OpenProcess(PROCESS_VM_OPERATION|PROCESS_VM_READ|
   PROCESS_VM_WRITE|PROCESS_QUERY_INFORMATION, FALSE, pid);


  _lvi=(LVITEM*)VirtualAllocEx(process, NULL, sizeof(LVITEM),
   MEM_COMMIT, PAGE_READWRITE);
  _item=(char*)VirtualAllocEx(process, NULL, 512, MEM_COMMIT,
   PAGE_READWRITE);
 
  _subitem1=(char*)VirtualAllocEx(process, NULL, 512, MEM_COMMIT,
   PAGE_READWRITE);
  _subitem2=(char*)VirtualAllocEx(process, NULL, 512, MEM_COMMIT,
   PAGE_READWRITE);
  _subitem3=(char*)VirtualAllocEx(process, NULL, 512, MEM_COMMIT,
   PAGE_READWRITE);
  _subitem4=(char*)VirtualAllocEx(process, NULL, 512, MEM_COMMIT,
   PAGE_READWRITE);
  _subitem5=(char*)VirtualAllocEx(process, NULL, 512, MEM_COMMIT,
   PAGE_READWRITE);
  _subitem6=(char*)VirtualAllocEx(process, NULL, 512, MEM_COMMIT,
   PAGE_READWRITE);
  _subitem7=(char*)VirtualAllocEx(process, NULL, 512, MEM_COMMIT,
   PAGE_READWRITE);
  _subitem8=(char*)VirtualAllocEx(process, NULL, 512, MEM_COMMIT,
   PAGE_READWRITE);


  lvi.cchTextMax=512;


   
  CFileDialog fileOpen(FALSE, “CSV저장”,NULL,OFN_HIDEREADONLY,”CSV파일 (*.csv)|*.csv|”,cwnd);
  if(filename.GetLength() > 0 || fileOpen.DoModal() == IDOK){


   CString mode = “”;
   bool header = false;
   if(filename.GetLength() == 0){
    mode =”wt”;
    filename = fileOpen.GetPathName();
    header = true;
   } else {
    mode =”a”;
   }


   FILE * out = fopen(filename,mode);
   if(header == true){
    fprintf(out, “\”순번\”,\”이름\”,\”직책\”,\”부서명\”,\”회사명\”,\”보직/담당업무\”,\”전화번호\”,\”핸드폰\”,\”이메일\”\n”);
   }
     
   for(i=0; i<count; i++) {
    lvi.iSubItem=0;
    lvi.pszText=_item;
    ::WriteProcessMemory(process, _lvi, &lvi, sizeof(LVITEM), NULL);
    ::SendMessage(hListView, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)_lvi);


    lvi.iSubItem=1;
    lvi.pszText=_subitem1;
    ::WriteProcessMemory(process, _lvi, &lvi, sizeof(LVITEM), NULL);
    ::SendMessage(hListView, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)_lvi);


    lvi.iSubItem=2;
    lvi.pszText=_subitem2;
    ::WriteProcessMemory(process, _lvi, &lvi, sizeof(LVITEM), NULL);
    ::SendMessage(hListView, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)_lvi);


    lvi.iSubItem=3;
    lvi.pszText=_subitem3;
    ::WriteProcessMemory(process, _lvi, &lvi, sizeof(LVITEM), NULL);
    ::SendMessage(hListView, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)_lvi);


    lvi.iSubItem=4;
    lvi.pszText=_subitem4;
    ::WriteProcessMemory(process, _lvi, &lvi, sizeof(LVITEM), NULL);
    ::SendMessage(hListView, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)_lvi);


    lvi.iSubItem=5;
    lvi.pszText=_subitem5;
    ::WriteProcessMemory(process, _lvi, &lvi, sizeof(LVITEM), NULL);
    ::SendMessage(hListView, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)_lvi);


    lvi.iSubItem=6;
    lvi.pszText=_subitem6;
    ::WriteProcessMemory(process, _lvi, &lvi, sizeof(LVITEM), NULL);
    ::SendMessage(hListView, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)_lvi);


    lvi.iSubItem=7;
    lvi.pszText=_subitem7;
    ::WriteProcessMemory(process, _lvi, &lvi, sizeof(LVITEM), NULL);
    ::SendMessage(hListView, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)_lvi);


    //lvi.iSubItem=8;
    //lvi.pszText=_subitem8;
    //::WriteProcessMemory(process, _lvi, &lvi, sizeof(LVITEM), NULL);
    //::SendMessage(hListView, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)_lvi);


    ::ReadProcessMemory(process, _item, item, 512, NULL);
    ::ReadProcessMemory(process, _subitem1, subitem1, 512, NULL);
    ::ReadProcessMemory(process, _subitem2, subitem2, 512, NULL);
    ::ReadProcessMemory(process, _subitem3, subitem3, 512, NULL);
    ::ReadProcessMemory(process, _subitem4, subitem4, 512, NULL);
    ::ReadProcessMemory(process, _subitem5, subitem5, 512, NULL);
    ::ReadProcessMemory(process, _subitem6, subitem6, 512, NULL);
    ::ReadProcessMemory(process, _subitem7, subitem7, 512, NULL);
    //::ReadProcessMemory(process, _subitem8, subitem8, 512, NULL);



    char output[2048];
    sprintf(output, “\”%d\”,\”%s\”,\”%s\”,\”%s\”,\”%s\”,\”%s\”,\”%s\”,\”%s\”,\”%s\””,lineCount,item,subitem1,subitem2,subitem3,subitem4,subitem5,subitem6,subitem7);
    fprintf(out,”%s\n”,output);
    lineCount++;
   }
   fclose(out);
  }


  ::VirtualFreeEx(process, _lvi, 0, MEM_RELEASE);
  ::VirtualFreeEx(process, _item, 0, MEM_RELEASE);
  ::VirtualFreeEx(process, _subitem1, 0, MEM_RELEASE);
  ::VirtualFreeEx(process, _subitem2, 0, MEM_RELEASE);
  ::VirtualFreeEx(process, _subitem3, 0, MEM_RELEASE);
  ::VirtualFreeEx(process, _subitem4, 0, MEM_RELEASE);
  ::VirtualFreeEx(process, _subitem5, 0, MEM_RELEASE);
  ::VirtualFreeEx(process, _subitem6, 0, MEM_RELEASE);
  ::VirtualFreeEx(process, _subitem7, 0, MEM_RELEASE);

 }
}

ITX컴퓨터를 이용한 웹디스크 DIY

상용웹디스크에 관심이 있어 이것저것 알아보았다.

블x , C-Dxxx , 와이xxx 

웹디스크의 장점:



  1. 소모 전력이 적다 (보통 30~60W)
  2. 이동성 (크기가 작다)
  3. 관리가 쉽다 (관리인터페이스 제공)

웹디스크의 단점

    1. 가격이 비싸다.
    2. 확장기능이 별로 없다. (소프트웨어)
    3. 하드웨어 변경할 수 없다.(일부)

선택시 고려되는 점
   1. 가격
   2. 유지비용(전기세, 부품교체비용)
   3. 확장성(웹하드, 웹메일, FTP 등등)
   4. 이동성

 이런저런 넘들을 살펴보니 필요하긴한데 너무 고가 인데다가 활용성이 서브컴을 한대 활용하는것에 비해 떨어진다. 또한 웹서버 기능을 제외하면 일반 저장장치를 사용하는것이 나을듯하고 파일서버로 구축하는 경우에 이동성을 포기하고 저전력 CPU와 mATX 케이스를 이용해서 파일서버를 구축하는것이 나을것 같다. (저전력의 문제는  저전력 Sempron 계열이나 신형 코어2듀오계열의 Cel CPU를 이용하고 120W이하의 Pico-PSU를 이용하면 해결된다. 삼x 에서 나오는 루x 계열중에 모바일  cpu를 이용한 작은 데스크톱같은경우)

 고심끝에 가격은 mATX보다 비싸지만 이동성과 미관을 고려해 ITX를 이용해 DIY하기로 하였다.
 DIY를 위해 구매한 사양은 다음과 같다.

    IK-177 C7 1.5G 메인보드+Gigabit Lan Card
    DDR2 512M
    WD 400G
    WL54 PCI무선랜카드
    WD-M300 ITX-CASE
 
   설치 순서  
   1. 바이오스에서 No Error를 선택하여 Keyboard 마우스 없이 부팅되도 에러가 발생하지 않도록 설정
   2. 운영체제를 설치 한뒤에 자동로그인 가능하도록 설정 (리눅스 계열은 설치후에 자동로그인 필요 없다)
   3. APM을 설치후에 간단히 환경에 맞추어 세팅한다.
   4. 필요한 경우 메일서버를 설치(본인은 James를 이용)후 세팅
   5. 웹하드를 설치 ( 본인은 shade웹하드 이용)
   6. 웹메일을 설치 ( 본인은 nocc 웹메일 이용)
   7. FTP를 설치한다.
   8. SSH를 설치한다.
   9. DnsEver를 이용하여 DDNS설정 (domain을 가지고 있다면)
   10. 재부팅 후 완벽히 실행 되는 지 검사후 모니터, 키보드, 마우스 분리하면 완료됨

VMWare 64bit 머신에서 32bit Guest 운영체제 설치 방법

XP에서 (물론 32bit) VMWare에 Solaris10을 설치해 보았다. 그런데 64Bit운영체제인데 설정이 32bit로 되어 있다고 나온다. 물론 실행도 안된다. VMWare에서 찾아보니 다음과 같은 내용이 있었다.
Solaris10버전은 CPU가 64bit이면 자동으로 64bit로 설치가 되므로 VMWare설정에 아래의 내용을 추가 해주면 64 CPU에서 32로 강제로 설정된다.

———– 원문 ——————-
VMware Workstation
 
 Details
 
  I have a 64-bit host machine with a processor that is not supported by Workstation for 64-bit guests. When I try to install Solaris 10 as a 32-bit guest operating system, Workstation displays an error message indicating that I do not have a supported 64-bit processor. How can I install Solaris 10 as a 32-bit guest operating system?
 
Solution
 
 
When the Solaris 10 guest detects the host processor’s 64-bit capability during installation, it attempts to enter longmode, and Workstation displays an error message indicating that you do not have a supported 64-bit processor. You may be able to work around this problem by suppressing the longmode feature. Try adding the following line to the guest virtual machine’s configuration (.vmx) file:
monitor_control.disable_longmode = 1


Once you have successfully installed Solaris 10 in 32-bit mode, VMware recommends that you remove the line from the configuration file, since this setting might cause problems with some applications. To force Solaris 10 to boot in 32-bit mode on a 64-bit host, execute the following command from a command line prompt within the guest:
eeprom boot-file=kernel/unix
This command requires superuser privileges.


Note: If you upgrade the guest operating system (for example, from Solaris 10 Upgrade 1 to Solaris 10 Upgrade 2), you need to re-execute the eeprom command because the entry is automatically removed on upgrade.


 ————— www.vmware.com ——————

SMTP서버 테스트

Mail-abuse.org에서 제공하는 테스트에 대해 알아보도록 하겠습니다.


이 자료는 mail-abuse.org에서 제공하는 Relay 테스트에 대한 자료로서, 여러분께서 관리하시는 메일서버에서 텔넷 명령(telnet)을 이용하여, Relay 테스트를 받으실 수 있습니다 . Mail-abuse.org에서는 19번의 테스트를 하며, 1가지에도 해당되어서는 안됩니다.


C:\> telnet relay-test.mail-abuse.org : telnet 명령으로 접속합니다.
Trying…
Connected to cygnus.mail-abuse.org.
Escape character is ‘^]’.
Connecting to 147.46.xx.xx …

## 참고 자료 ############
http://www.mail-abuse.org
Certcc.or.kr의 “김상철” 연구원님의 “메일서버의 SPAM RELAY TEST”
http://certcc.or.kr/paper/tr2001/tr2001-06/spam_relay_test.pdf