2009년 11월 5일 목요일

API 몇가지 팁 (네트워크 전용 외)

1  [Tip] 인터넷 연결상태 체크
/////////////////////////////////////////////////////////////


tcp / ip로 데이터를 전송하기 전에 인터넷이 연결이 되어져 있는지 안되어져 있는지 체크를 하는 거거든요...

뭐 ^^ 워낙 허접한지라 어디서 가져 왔는지는 모르겠지만 쓰고 있는 방법이 있어서 올립니다.

 

중복되는 자료라면 토달아 주세요...

 

BOOL IsConnectInternet()

{

   DWORD dwFlags;

   BOOL bChkInternet = InternetGetConnectedState(&dwFlags,0);

   if(!bChkInternet){

       AfxMessageBox("Chk U Internet !!");

       return FALSE;

   }

}

 

원래 dwFlags 요넘으로 인터넷이 연결이 되어져 있다면 어떤 상태 받아 오거든요...

걍 구찮아서 BOOL로만 체크 했습니다.

필요하신분은 잘 ^^ 알맞게 맞춰 쓰세용..

 

설마 요즘도 모뎀을 사용하시는 분들이 있겠죠....

그때 클라이언트의 연결정보를 요청해서 모뎀이면 "쉬트~~~ 모뎀 버려라" 하게끔 할때도 좋겠네요

 

 

msdn을 참고

 

Retrieves the connected state of the local system
BOOL InternetGetConnectedState(    

   LPDWORD lpdwFlags,    

   DWORD dwReserved );

 

Parameters

lpdwFlags
[out] Pointer to an unsigned long integer variable where the connection description should be returned. This can be a combination of the following values:
INTERNET_CONNECTION_CONFIGURED
Local system has a valid connection to the Internet, but it may or may not be currently connected.
INTERNET_CONNECTION_LAN
Local system uses a local area network to connect to the Internet.
INTERNET_CONNECTION_MODEM
Local system uses a modem to connect to the Internet.
INTERNET_CONNECTION_MODEM_BUSY
No longer used.
INTERNET_CONNECTION_OFFLINE
Local system is in offline mode.
INTERNET_CONNECTION_PROXY
Local system uses a proxy server to connect to the Internet.
INTERNET_RAS_INSTALLED
Local system has RAS installed.
dwReserved
[in] Reserved. Must be set to zero.
Return Value

Returns TRUE if there is an Internet connection, or FALSE otherwise.

 


Function Information

Stock Implementation wininet.dll
Custom Implementation No
Header Wininet.h
Import library Wininet.lib
Minimum availability Internet Explorer 4.0
Minimum operating systems Windows NT 4.0, Windows 95, Windows CE 2.12

 

2 [Tip] 키보드/마우스 입력 막기

////////////////////////////////////////////

키보드와 마우스의 입력을 막아서 컴퓨터가 먹통이 된 것 같은 효과를 내는 방법을

소개하고자 글을 씁니다.

시스템 메시지 훅킹(hooking)을 하는 방법이 있는데.. 이건 좀 복잡하고..

하핫.. 간단히 하는 방법을 발견했습니다.

바로 윈도우즈 API 함수 중에 "BlockInput"이라는 함수가 있습니다.

Requirements  
 Windows NT/2000/XP: Included in Windows 2000 and later.
 Windows 95/98/Me: Included in Windows 98 and later.
 Header: Declared in Winable.h.
 Library: Use User32.lib.

98 계열.. 2000 계열에서 사용할 수 있으니 별 문제가 없을테구요...

#inlcude <Winable.h>

이렇게 헤더파일을 포함시켜주시고요..

BlockInput(TRUE);

이렇게 하면 키보드와 마우스 입력이 차단됩니다.

BlockInput(FALSE);

이렇게 하면 다시 입력이 되고요...

저 함수를 호출한 애플리케이션 말고도 윈도우즈 전체에서 입력이 막혀버립니다.

하하.. 잘 쓰면 유용할 듯 싶네요.

수고하세요.


3 [Tip] Window handle로 부터 *.exe 이름 알아내기

/////////////////////////////////////////////

function WindowToExe( window : dword ) : String;
var
 pid : dword;
 pl : TProcessList;
 i1 : integer;
begin
 Result := '';
 pl := nil;
 GetWindowThreadProcessID( Window, @pid );

 if pid <> 0 then
 begin
    pl := GetProcessList;
    for i1 := 0 to high( pl ) do
       if pl[ i1 ].pid = pid then
       begin
          Result := pl[ i1 ].name;
          break;
       end;
 end;
end;
 

4 [Tip] 네트워크 드라이브 연결

/////////////////////////////////////////////////

네트워크 드라이브를 연결하는 방법입니다.  

네트워크 드라이브를 만들기 위해서는 Win32 API 함수인 WNetAddConnection2() 함수를 이용합니다.
(WNetAddConnection() 함수를 쓸 수도 있지만 몇가지 제약이 있습니다.)
이 함수의 인자는 첫번째가 NETRESOURCE 타입의 구조체의 포인터, 두번째와 세번째는 계정 패스워드와 유저
네임, 네번째는 옵션입니다. (이 옵션을 CONNECT_UPDATE_PROFILE으로 설정하면 OS가 네트워크 드라이브를
기억해서 로그온할 때마다 다시 나타납니다.)

NETRESOURCE 구조체의 멤버중 lpLocalName은 드라이브 문자를 가지는 문자열이고, lpRemoteName은 연결할
공유 디렉토리의 UNC 네임입니다. UNC 네임이란, 컴퓨터 이름을 포함한 네트워크상의 전체 경로를 말합니다.
예를 들어, 컴퓨터 이름이 MyCom이고 공유 디렉토리 이름이 SharedDirectory라면, UNC 네임은 다음과 같습니다.
\\MyCom\SharedDirectory

사용하는 방법은 다음과 같습니다. 다음의 소스는 공유하려는 디렉토리가 현재 컴퓨터에 있을 때입니다.

void __fastcall TForm1::Button1Click(TObject *Sender)
{
   NETRESOURCE NetRes;
   NetRes.dwType = RESOURCETYPE_DISK;
   NetRes.lpLocalName  = "Z:";
   NetRes.lpRemoteName = "\\\\컴퓨터이름\\공유디렉토리";
   NetRes.lpProvider   = NULL;
   DWORD Result = WNetAddConnection2(&NetRes, "", "", CONNECT_UPDATE_PROFILE);
   if(Result==NO_ERROR)
       ShowMessage("네트웍 드라이브가 생성되었습니다.");
}

원래, UNC 이름의 경우, 컴퓨터이름으로 . (점)을 주면 현재 컴퓨터를 가리키게 되어있는데..
이 API에서는 안먹히더군요. GetComputerName() 함수를 쓰면 현재 컴퓨터 이름을 알아낼 수 있습니다.

만약 원격 컴퓨터라면, WNetAddConnection2() 함수의 두번째와 세번째 인자로 해당 원격 컴퓨터의 계정
패스워드와 유저네임을 넘겨야 합니다.

만약 연결하려는 원격 컴퓨터가 현재 도메인내에 있는 것이 아니라 인터넷상의 컴퓨터라면, UNC네임에
IP 주소를 써서 연결할 수 있습니다. IP주소를 쓸 때는 컴퓨터 이름 자리에 그대로 IP주소를 써넣으면
됩니다. 예를 들어서, IP가 210.145.45.233이라면,
NetRes.lpRemoteName = "\\\\210.145.45.233\\공유디렉토리";
이렇게 하면 됩니다.

실제로, 인터넷에서 드라이브 형태로 서비스를 하는 업체들은 대부분 이 WNetAddConnection2() 함수를
이용한답니다.

반대로 연결을 해제할 때는 WNetCancelConnection2() 함수를 쓰면 됩니다.
(WNetAddConnection2() 함수가 있다는 것은 볼랜드 저팬 사이트에서 알았습니다.)


5 [Tip] Ctrl+Alt+Del키 안먹게 하기 (Win98전용)

/////////////////////////////////////////////////////////

Windows 95/98에서 ALT-CTL-DEL DialogBox를 나타나지 않게 하려면
SystemParametersInfo API 함수를 호출하고 화변보호기가 실행된것처럼 OS가
생각하도록 속이면된다. 화면보호기가 실행되고 있는 중에는 OS는 ALT-CTL-DEL
DialogBox를 활성화 시키지 않는다.

__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    // Disable CTRL-ALT-DEL construction
    SystemParametersInfo(SPI_SCREENSAVERRUNNING, TRUE , NULL,0);
}

__fastcall TForm1::~TForm1()
{
    // Enabled CTRL-ALT-DEL when we close
    SystemParametersInfo(SPI_SCREENSAVERRUNNING, FALSE , NULL,0);
}

Note : 정말 필요할때에만 CTRL-ALT-DEL을 불가능하게 하도록 한다. 만일 프로그램이
       폭주한다면, destructor가 실행되지 않을수 있고 재부팅 하기 전까지는
       CTRL-ALT-DEL DialogBox가 불가능한 상태로 남아있게 된다.

Note : SystemParametersInfo의 속임수는 Windows NT에서는 작동하지 않는다.


6  [Tip] rawprt.exe (Win32 application to do > PRN:)

/////////////////////////////////////////////////////////////


*
*            rawprt.exe  (Win32 application to do > PRN:)
*                    by SHIMA (July 1998)
*/

#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <windows.h>
#include <winspool.h>

#define    BUF_LEN    0x1000

char printer_name[256];
unsigned char p_buf[BUF_LEN];
int p_len;

static HANDLE printer;

BOOL f_rawerr;
BOOL f_rawwait;

void Win32cPrtinterInit(char *s);
void Win32cPrtinterEnd(void);
void PrFlush(char *pr_buf, int pr_buf_len);

void main(int argc, char **argv)
{
   FILE *fp;
   int i;
   char *p = NULL;
   int ch;

   fp = stdin;
   setmode(fileno(fp), O_BINARY);
   fp->flags |= _F_BIN;

   for(i = 1; i < argc; i++){
       if(argv[i][0] != '-'){
           if((fp = fopen(argv[i], "rb")) == NULL){
               fprintf(stderr, "Cannot open %s.", argv[i]);
               exit(1);
           }
           break;
       }
       switch(argv[i][1]){
         case 'p': p = argv[i]+2;
                     break;
       }
   }
   if(isatty(fileno(fp))){
       fprintf(stderr, "Input device is a character device.");
       fprintf(stderr,
       "\n\nrawprt Ver.0.1: output data to printer (copy /b <file> PRN:)\n"
       "written by SHIMA(July 24, 1998)\n\n"
       "rawprt [-p<printer_name>] [<file>]\n"
       "default input : stdin\n"
       "default output: stdprn\n");
       exit(2);
   }
   Win32cPrtinterInit(p);
   while((ch=getc(fp)) != EOF){
       p_buf[p_len] = ch;
       if(++p_len >= BUF_LEN){
           PrFlush(p_buf, p_len);
           p_len = 0;
       }
   }
   PrFlush(p_buf, p_len);
   Win32cPrtinterEnd();
}

void AbortRawPrint(void)
{
   if(printer){
       AbortPrinter(printer);
       printer = NULL;
   }
   f_rawerr = TRUE;
}

void Win32cPrtinterInit(char *s)
{
   DOC_INFO_1 di;
   char *p;

   f_rawerr = FALSE;
   if (s == NULL) {    /* default printer */
       GetProfileString("windows", "device", "", printer_name, 256);
       if ( (p = strchr(printer_name, ',')) != NULL )
           *p = '\0';
   } else
       strncpy(printer_name, s, 256);

   if (!OpenPrinter(printer_name, &printer, NULL)) {
       printer = NULL;
       fprintf(stderr,
           "OpenPrinter() failed for \042%s\042, error code = %d",
           printer_name, GetLastError());
           AbortRawPrint();
           exit(3);
   }
   /* from here until ClosePrinter, should AbortPrinter on error */
   di.pDocName = "dviprt";
   di.pOutputFile = NULL;
   di.pDatatype = "RAW";
   if (!StartDocPrinter(printer, 1, (LPBYTE)&di)) {
       AbortRawPrint();
       fprintf(stderr,
           "StartDocPrinter() failed for \042%s\042, error code = %d",
           printer_name, GetLastError());
       exit(4);
   }
   return;
}

void Win32cPrtinterEnd(void)
{
   if (!EndDocPrinter(printer)) {
       AbortRawPrint();
       fprintf(stderr,
           "EndDocPrinter() failed for \042%s\042, error code = %d",
           printer_name, GetLastError());
   }
   else if (!ClosePrinter(printer)) {
       fprintf(stderr,
           "CloseDocPrinter() failed for \042%s\042, error code = %d",
           printer_name, GetLastError());
       AbortRawPrint();
   }
   printer = NULL;
}


void PrFlush(char *pr_buf, int pr_buf_len)
{
   DWORD written;

   if(!pr_buf_len)
       return;

   if (!WritePrinter(printer, (LPVOID)pr_buf, pr_buf_len, &written)) {
       AbortPrinter(printer);
       fprintf(stderr,
           "WritePrinter() failed for \042%s\042, error code = %d",
           printer_name, GetLastError());
       exit(5);
   }
   return;

댓글 없음:

댓글 쓰기