home *** CD-ROM | disk | FTP | other *** search
/ PC World 2004 November / PCWorld_2004-11_cd.bin / software / temacd / poweroff / pwroff30.exe / src / remote.c < prev    next >
C/C++ Source or Header  |  2002-02-16  |  14KB  |  409 lines

  1. #include "poweroff.h"
  2. #include <winsock2.h>
  3.  
  4. #define MAXLEN_PHYSADDR 8
  5.  
  6. typedef struct {
  7.   DWORD dwIndex;
  8.   DWORD dwPhysAddLen;
  9.   BYTE  bPhysAddr[MAXLEN_PHYSADDR];
  10.   DWORD dwAddr;
  11.   DWORD dwType;
  12. } MIB_IPNETROW, *PMIB_IPNETROW;
  13.  
  14. typedef struct {
  15.   DWORD        dwNumEntries;
  16.   MIB_IPNETROW table[100];
  17. } MIB_IPNETTABLE, *PMIB_IPNETTABLE;
  18.  
  19. typedef struct {
  20.     unsigned char Ttl;                         // Time To Live
  21.     unsigned char Tos;                         // Type Of Service
  22.     unsigned char Flags;                       // IP header flags
  23.     unsigned char OptionsSize;                 // Size in bytes of options data
  24.     unsigned char *OptionsData;                // Pointer to options data
  25. } IP_OPTION_INFORMATION, * PIP_OPTION_INFORMATION;
  26.  
  27. typedef struct {
  28.     DWORD Address;                             // Replying address
  29.     unsigned long  Status;                     // Reply status
  30.     unsigned long  RoundTripTime;              // RTT in milliseconds
  31.     unsigned short DataSize;                   // Echo data size
  32.     unsigned short Reserved;                   // Reserved for system use
  33.     void *Data;                                // Pointer to the echo data
  34.     IP_OPTION_INFORMATION Options;             // Reply options
  35. } IP_ECHO_REPLY, * PIP_ECHO_REPLY;
  36.  
  37.  
  38.  
  39.  
  40. DWORD (WINAPI *GetIpNetTable)(PMIB_IPNETTABLE pIpNetTable,PULONG pdwSize,BOOL bOrder);
  41. HANDLE (WINAPI *IcmpCreateFile)(void); 
  42. DWORD (WINAPI *IcmpSendEcho)(HANDLE IcmpHandle,DWORD DestinationAddress,LPVOID RequestData,WORD RequestSize,PIP_OPTION_INFORMATION RequestOptions,LPVOID ReplyBuffer,DWORD ReplySize,DWORD Timeout);
  43. BOOL (WINAPI *IcmpCloseHandle)(HANDLE IcmpHandle); 
  44.  
  45.  
  46. void BrowseComputers(HWND hWnd)
  47. {
  48.   BROWSEINFO bi;
  49.   char buffer[MAX_PATH]="";
  50.   ITEMIDLIST *ppidl;
  51.   LPMALLOC malc;
  52.  
  53.   Log("BrowseComputers start");
  54.   SHGetMalloc(&malc);
  55.   SHGetSpecialFolderLocation(hWnd,CSIDL_NETWORK,&ppidl);
  56.   bi.hwndOwner=hWnd;
  57.   bi.pidlRoot=ppidl;
  58.   bi.pszDisplayName=buffer;
  59.   bi.lpszTitle="Select remote computer";
  60.   bi.ulFlags=BIF_BROWSEFORCOMPUTER;
  61.   bi.lpfn=NULL;
  62.   bi.lParam=0;
  63.   if (SHBrowseForFolder(&bi)!=NULL)
  64.     SetDlgItemText(hWnd,IDC_COMPUTER,buffer);
  65.   malc->lpVtbl->Free(malc,ppidl);
  66.   Log("BrowseComputers end, computer=%s",buffer);
  67. }
  68.  
  69. void EnableRemoteFields(HWND hWnd)
  70. {
  71.   Log("EnableRemoteFields start");
  72.   if (IsDlgButtonChecked(hWnd,IDC_REMOTE_NT))
  73.   {
  74.     EnableWindow(GetDlgItem(hWnd,IDC_REMOTE_CREDENTIALS),TRUE);
  75.     EnableWindow(GetDlgItem(hWnd,IDC_REMOTE_PORT),FALSE);
  76.     EnableWindow(GetDlgItem(hWnd,IDC_REMOTE_SCHEDULE),FALSE);
  77.     if (IsDlgButtonChecked(hWnd,IDC_REMOTE_CREDENTIALS))
  78.     {
  79.       EnableWindow(GetDlgItem(hWnd,IDC_REMOTE_USERNAME),FALSE);
  80.       EnableWindow(GetDlgItem(hWnd,IDC_REMOTE_PASSWORD),FALSE);
  81.       EnableWindow(GetDlgItem(hWnd,IDC_REMOTE_SAVE_PASSWORD),FALSE);
  82.     }
  83.     else
  84.     {
  85.       EnableWindow(GetDlgItem(hWnd,IDC_REMOTE_USERNAME),TRUE);
  86.       EnableWindow(GetDlgItem(hWnd,IDC_REMOTE_PASSWORD),TRUE);
  87.       EnableWindow(GetDlgItem(hWnd,IDC_REMOTE_SAVE_PASSWORD),TRUE);
  88.     }
  89.   }
  90.   else
  91.   {
  92.     EnableWindow(GetDlgItem(hWnd,IDC_REMOTE_PORT),TRUE);
  93.     EnableWindow(GetDlgItem(hWnd,IDC_REMOTE_PASSWORD),TRUE);
  94.     EnableWindow(GetDlgItem(hWnd,IDC_REMOTE_SAVE_PASSWORD),TRUE);
  95.     EnableWindow(GetDlgItem(hWnd,IDC_REMOTE_SCHEDULE),TRUE);
  96.     EnableWindow(GetDlgItem(hWnd,IDC_REMOTE_CREDENTIALS),FALSE);
  97.     EnableWindow(GetDlgItem(hWnd,IDC_REMOTE_USERNAME),FALSE);
  98.   }
  99.   Log("EnableRemoteFields end");
  100. }
  101.  
  102. BOOL FAR PASCAL RemoteProc(HWND hWnd, unsigned message,DWORD wParam, LONG lParam)
  103. {
  104.   static PowerSettings *ps;
  105.  
  106.   switch (message) 
  107.   {
  108.     case WM_INITDIALOG:
  109.       ps=(PowerSettings*)lParam;
  110.       SetDlgItemText(hWnd,IDC_COMPUTER,ps->remote.computer_name);
  111.       if (ps->windowsversion.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS)
  112.       {
  113.         ps->remote.use_nt=0;
  114.         EnableWindow(GetDlgItem(hWnd,IDC_REMOTE_NT),FALSE);
  115.       }
  116.       CheckDlgButton(hWnd,IDC_REMOTE_NT,ps->remote.use_nt?BST_CHECKED:BST_UNCHECKED);
  117.       if (!ps->remote.use_nt)
  118.       {
  119.         char str[40];
  120.  
  121.         sprintf(str,"%d",ps->remote.port);
  122.         SetDlgItemText(hWnd,IDC_REMOTE_PORT,str);
  123.         CheckDlgButton(hWnd,IDC_REMOTE_SAVE_PASSWORD,ps->remote.save_password?BST_CHECKED:BST_UNCHECKED);
  124.         CheckDlgButton(hWnd,IDC_REMOTE_SCHEDULE,ps->remote.schedule_remote?BST_CHECKED:BST_UNCHECKED);
  125.       }
  126.       CheckDlgButton(hWnd,IDC_REMOTE_CREDENTIALS,ps->remote.current_credentials?BST_CHECKED:BST_UNCHECKED);
  127.       SetDlgItemText(hWnd,IDC_REMOTE_USERNAME,ps->remote.username);
  128.       SetDlgItemText(hWnd,IDC_REMOTE_PASSWORD,"********");
  129.       EnableRemoteFields(hWnd);
  130.       return TRUE;
  131.     case WM_COMMAND:
  132.       switch (LOWORD(wParam))
  133.       {
  134.         case IDCANCEL:
  135.           EndDialog(hWnd,TRUE);
  136.           break;
  137.         case IDOK:
  138.           {
  139.             char str[40];
  140.  
  141.             GetDlgItemText(hWnd,IDC_COMPUTER,ps->remote.computer_name,100);
  142.             ps->remote.use_nt=IsDlgButtonChecked(hWnd,IDC_REMOTE_NT);
  143.             if (!ps->remote.use_nt)
  144.             {
  145.               GetDlgItemText(hWnd,IDC_REMOTE_PORT,str,40);
  146.               ps->remote.port=atoi(str);
  147.               if (ps->remote.port<=0)
  148.                 ps->remote.port=LISTEN_PORT;
  149.               ps->remote.schedule_remote=IsDlgButtonChecked(hWnd,IDC_REMOTE_SCHEDULE);
  150.             }
  151.             else
  152.             {
  153.               ps->remote.port=LISTEN_PORT;
  154.               ps->remote.password[0]='\0';
  155.               ps->remote.save_password=0;
  156.               ps->remote.schedule_remote=0;
  157.             }
  158.             ps->remote.current_credentials=IsDlgButtonChecked(hWnd,IDC_REMOTE_CREDENTIALS);
  159.             GetDlgItemText(hWnd,IDC_REMOTE_USERNAME,ps->remote.username,40);
  160.             GetDlgItemText(hWnd,IDC_REMOTE_PASSWORD,str,40);
  161.             if (strcmp(str,"********"))
  162.               strcpy(ps->remote.password,str);
  163.             ps->remote.save_password=IsDlgButtonChecked(hWnd,IDC_REMOTE_SAVE_PASSWORD);
  164.             EndDialog(hWnd,TRUE);
  165.           }
  166.           break;
  167.         case IDC_BROWSE:
  168.           BrowseComputers(hWnd);
  169.           break;
  170.         case IDC_REMOTE_NT:
  171.         case IDC_REMOTE_CREDENTIALS:
  172.           EnableRemoteFields(hWnd);
  173.       }
  174.       break;
  175.       default:
  176.          break;
  177.   }
  178.   return FALSE;
  179. }
  180.  
  181. int IsValidMACAddress(char *str)
  182. {
  183.   int x;
  184.  
  185.   Log("IsValidMACAddress start");
  186.   if (strlen(str)!=12)
  187.   {
  188.     Log("Length is not 12");
  189.     return 0;
  190.   }
  191.   for (x=0;x<12;x++)
  192.   {
  193.     str[x]=toupper(str[x]);
  194.     if (strchr("0123456789ABCDEF",str[x])==NULL)
  195.     {
  196.       Log("MAC address contains invalid character");
  197.       return 0;
  198.     }
  199.   }
  200.   Log("IsValidMACAddress end");
  201.   return 1;
  202. }
  203.  
  204. int IsValidIPAddress(char *str)
  205. {
  206.   int a1,a2,a3,a4;
  207.  
  208.   Log("IsValidIPAddress start");
  209.   if (sscanf(str,"%d.%d.%d.%d",&a1,&a2,&a3,&a4)!=4)
  210.     return 0;
  211.   if (a1<0 || a1>255)
  212.     return 0;
  213.   if (a2<0 || a2>255)
  214.     return 0;
  215.   if (a3<0 || a3>255)
  216.     return 0;
  217.   if (a4<0 || a4>255)
  218.     return 0;
  219.   Log("IsValidIPAddress end");
  220.   return 1;
  221. }
  222.  
  223. BOOL FAR PASCAL WOLProc(HWND hWnd, unsigned message,DWORD wParam, LONG lParam)
  224. {
  225.   static PowerSettings *ps;
  226.  
  227.   switch (message) 
  228.   {
  229.     case WM_INITDIALOG:
  230.       {
  231.         int b1=0,b2=0,b3=0,b4=0;
  232.  
  233.         ps=(PowerSettings*)lParam;
  234.         SetDlgItemText(hWnd,IDC_MAC_ADDRESS,ps->remote.mac_address);
  235.         sscanf(ps->remote.ip_address,"%d.%d.%d.%d",&b1,&b2,&b3,&b4);
  236.         SendDlgItemMessage(hWnd,IDC_IP_ADDRESS,IPM_SETADDRESS,0,MAKEIPADDRESS(b1,b2,b3,b4));
  237.         sscanf(ps->remote.subnet_mask,"%d.%d.%d.%d",&b1,&b2,&b3,&b4);
  238.         SendDlgItemMessage(hWnd,IDC_SUBNET_MASK,IPM_SETADDRESS,0,MAKEIPADDRESS(b1,b2,b3,b4));
  239.         SendDlgItemMessage(hWnd,IDC_MAC_ADDRESS,EM_LIMITTEXT,12,0);
  240.       }
  241.       return TRUE;
  242.     case WM_COMMAND:
  243.       switch (LOWORD(wParam))
  244.       {
  245.         case IDCANCEL:
  246.           EndDialog(hWnd,TRUE);
  247.           break;
  248.         case IDOK:
  249.           {
  250.             DWORD ip;
  251.             char tmpstr[14];
  252.  
  253.             GetDlgItemText(hWnd,IDC_MAC_ADDRESS,tmpstr,14);
  254.             if (!IsValidMACAddress(tmpstr))
  255.             {
  256.               Error(ps,hWnd,"Invalid MAC address specified");
  257.             }
  258.             else
  259.             {
  260.               strcpy(ps->remote.mac_address,tmpstr);
  261.               SendDlgItemMessage(hWnd,IDC_IP_ADDRESS,IPM_GETADDRESS,0,(LPARAM)&ip);
  262.               sprintf(ps->remote.ip_address,"%d.%d.%d.%d",(int)FIRST_IPADDRESS(ip),
  263.                                                           (int)SECOND_IPADDRESS(ip),
  264.                                                           (int)THIRD_IPADDRESS(ip),
  265.                                                           (int)FOURTH_IPADDRESS(ip));
  266.               SendDlgItemMessage(hWnd,IDC_SUBNET_MASK,IPM_GETADDRESS,0,(LPARAM)&ip);
  267.               sprintf(ps->remote.subnet_mask,"%d.%d.%d.%d",(int)FIRST_IPADDRESS(ip),
  268.                                                            (int)SECOND_IPADDRESS(ip),
  269.                                                            (int)THIRD_IPADDRESS(ip),
  270.                                                            (int)FOURTH_IPADDRESS(ip));
  271.               EndDialog(hWnd,TRUE);
  272.             }
  273.           }
  274.           break;
  275.         case IDC_BUT_LOOKUP:
  276.           {
  277.             DWORD ip,ipsize;
  278.             char mac_address[20]="",str[20];
  279.             char acPingBuffer[64];
  280.             int x,y;
  281.             MIB_IPNETTABLE iptable;
  282.             HINSTANCE lh;
  283.             HANDLE ph;
  284.             PIP_ECHO_REPLY pIpe;
  285.  
  286.             SendDlgItemMessage(hWnd,IDC_IP_ADDRESS,IPM_GETADDRESS,0,(LPARAM)&ip);
  287.             ip=htonl(ip);
  288.             lh=LoadLibrary("icmp.dll");
  289.             if (lh==NULL)
  290.             {
  291.               DisplayLastError(ps,hWnd);
  292.               break;
  293.             }
  294.             IcmpCreateFile=(void*)GetProcAddress(lh,"IcmpCreateFile");
  295.             if (IcmpCreateFile ==NULL)
  296.             {
  297.               DisplayLastError(ps,hWnd);
  298.               FreeLibrary(lh);
  299.               break;
  300.             }
  301.             IcmpSendEcho=(void*)GetProcAddress(lh,"IcmpSendEcho");
  302.             if (IcmpSendEcho==NULL)
  303.             {
  304.               DisplayLastError(ps,hWnd);
  305.               FreeLibrary(lh);
  306.               break;
  307.             }
  308.             IcmpCloseHandle=(void*)GetProcAddress(lh,"IcmpCloseHandle");
  309.             if (IcmpCloseHandle==NULL)
  310.             {
  311.               DisplayLastError(ps,hWnd);
  312.               FreeLibrary(lh);
  313.               break;
  314.             }
  315.             if ((ph=IcmpCreateFile())==INVALID_HANDLE_VALUE)
  316.             {
  317.               DisplayLastError(ps,hWnd);
  318.               break;
  319.             }
  320.             memset(acPingBuffer, '\xAA', sizeof(acPingBuffer));
  321.             pIpe = (PIP_ECHO_REPLY)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,sizeof(IP_ECHO_REPLY) + sizeof(acPingBuffer));
  322.             if (pIpe == 0) 
  323.             {
  324.               Error(ps,hWnd,"Failed to allocate global ping packet buffer");
  325.               IcmpCloseHandle(ph);
  326.               FreeLibrary(lh);
  327.               GlobalFree(pIpe);
  328.               break;
  329.             }
  330.             pIpe->Data = acPingBuffer;
  331.             pIpe->DataSize = sizeof(acPingBuffer);      
  332.  
  333.             IcmpSendEcho(ph,ip,acPingBuffer,sizeof(acPingBuffer),NULL,pIpe,sizeof(IP_ECHO_REPLY) + sizeof(acPingBuffer),5000);
  334.             IcmpCloseHandle(ph);
  335.             FreeLibrary(lh);
  336.             GlobalFree(pIpe);
  337.  
  338.             lh=LoadLibrary("Iphlpapi.dll");
  339.             if (lh==NULL)
  340.             {
  341.               DisplayLastError(ps,hWnd);
  342.               break;
  343.             }
  344.             GetIpNetTable=(void*)GetProcAddress(lh,"GetIpNetTable");
  345.             if (GetIpNetTable==NULL)
  346.             {
  347.               DisplayLastError(ps,hWnd);
  348.               FreeLibrary(lh);
  349.               break;
  350.             }
  351.             ipsize=sizeof(iptable);
  352.             if (GetIpNetTable(&iptable,&ipsize,FALSE)!=NO_ERROR)
  353.             {
  354.               Error(ps,hWnd,"Error during GetIpNetTable()");
  355.               FreeLibrary(lh);
  356.               break;
  357.             }
  358.             for (x=0;x<(int)iptable.dwNumEntries && mac_address[0]=='\0';x++)
  359.             {
  360.               if (iptable.table[x].dwAddr==ip)
  361.               {
  362.                 for (y=0;y<(int)iptable.table[x].dwPhysAddLen;y++)
  363.                 {
  364.                   sprintf(str,"%02X",(int)iptable.table[x].bPhysAddr[y]);
  365.                   strcat(mac_address,str);
  366.                 }
  367.                 SetDlgItemText(hWnd,IDC_MAC_ADDRESS,mac_address);
  368.                 break;
  369.               }
  370.             }
  371.             FreeLibrary(lh);
  372.             if (mac_address[0]=='\0')
  373.             {
  374.               Error(ps,hWnd,"MAC address not found");
  375.               break;
  376.             }
  377.           }
  378.           break;
  379.       }
  380.       break;
  381.       default:
  382.          break;
  383.   }
  384.   return FALSE;
  385. }
  386.  
  387. void ShowRemoteDialog(HWND hWnd,PowerSettings *ps)
  388. {
  389.   FARPROC dlgproc;
  390.  
  391.   Log("ShowRemoteDialog start");
  392.   if (ps->action==WAKE_ON_LAN)
  393.   {
  394.     Log("Action=WOL");
  395.     dlgproc=MakeProcInstance((FARPROC)WOLProc,hInst);
  396.       if (DialogBoxParam(hInst,MAKEINTRESOURCE(IDD_WOL),hWnd,(DLGPROC)dlgproc,(LPARAM)ps)==-1)
  397.       DisplayLastError(ps,hWnd);
  398.       FreeProcInstance(dlgproc);
  399.   }
  400.   else
  401.   {
  402.     Log("Action!=WOL");
  403.     dlgproc=MakeProcInstance((FARPROC)RemoteProc,hInst);
  404.       if (DialogBoxParam(hInst,MAKEINTRESOURCE(IDD_REMOTE),hWnd,(DLGPROC)dlgproc,(LPARAM)ps)==-1)
  405.       DisplayLastError(ps,hWnd);
  406.       FreeProcInstance(dlgproc);
  407.   }
  408.   Log("ShowRemoteDialog end");
  409. }