win32.c
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:16k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * Copyright (c) 1996 The Regents of the University of California.
  3.  * All rights reserved.
  4.  * 
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *  This product includes software developed by the Network Research
  16.  *  Group at Lawrence Berkeley National Laboratory.
  17.  * 4. Neither the name of the University nor of the Laboratory may be used
  18.  *    to endorse or promote products derived from this software without
  19.  *    specific prior written permission.
  20.  * 
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  *
  33.  * This module contributed by John Brezak <brezak@apollo.hp.com>.
  34.  * January 31, 1996
  35.  *
  36.  * @(#) $Header: /cvsroot/nsnam/ns-2/common/win32.c,v 1.6 2006/02/21 15:20:18 mahrenho Exp $ (LBL)
  37.  */
  38. #ifdef WIN32
  39. #include <assert.h>
  40. #include <io.h>
  41. #include <process.h>
  42. #include <fcntl.h>
  43. #include <windows.h>
  44. #include <malloc.h>
  45. #include <string.h>
  46. #include <stdio.h>
  47. #include <time.h>
  48. #include <winsock.h>
  49. #include <tcl.h>
  50. #include "config.h"
  51. #include <locale.h>
  52. /* forward declarations */
  53. int WinGetUserName(ClientData, Tcl_Interp*, int ac, char**av);
  54. int WinGetHostName(ClientData, Tcl_Interp*, int ac, char**av);
  55. int WinPutRegistry(ClientData, Tcl_Interp*, int ac, char**av);
  56. int WinGetRegistry(ClientData, Tcl_Interp*, int ac, char**av);
  57. void TkConsoleCreate();
  58. int TkConsoleInit(Tcl_Interp* interp);
  59.         
  60. int
  61. uname(struct utsname *ub)
  62. {
  63.     char *ptr;
  64.     DWORD version;
  65.     SYSTEM_INFO sysinfo;
  66.     char hostname[4096];
  67.     
  68.     version = GetVersion();
  69.     GetSystemInfo(&sysinfo);
  70.     
  71.     switch (sysinfo.wProcessorArchitecture) {
  72.     case PROCESSOR_ARCHITECTURE_INTEL:
  73. (void)strcpy(ub->machine, "ix86");
  74. break;
  75.     case PROCESSOR_ARCHITECTURE_MIPS :
  76. (void)strcpy(ub->machine, "mips");
  77. break;
  78.     case PROCESSOR_ARCHITECTURE_ALPHA:
  79. (void)strcpy(ub->machine, "alpha");
  80. break;
  81.     case PROCESSOR_ARCHITECTURE_PPC:
  82. (void)strcpy(ub->machine, "ppc");
  83. break;
  84.     default:
  85. (void)strcpy(ub->machine, "unknown");
  86. break;
  87.     }
  88.     
  89.     if (version < 0x80000000) {
  90. (void)strcpy(ub->version, "NT");
  91.     }
  92.     else if (LOBYTE(LOWORD(version))<4) {
  93. (void)strcpy(ub->version, "Win32s");
  94.     }
  95.     else /* Win95 */ {
  96. (void)strcpy(ub->version, "Win95");
  97.     }
  98.     (void)sprintf(ub->release, "%u.%u",
  99.   (DWORD)(LOBYTE(LOWORD(version))),
  100.   (DWORD)(HIBYTE(LOWORD(version))));
  101.     (void)strcpy(ub->sysname, "Windows");
  102.     if (gethostname(hostname, sizeof(hostname)) == 0) {
  103. if (ptr = strchr(hostname, '.'))
  104.     *ptr = '';
  105.     }
  106.     else {
  107. perror("uname: gethostname failed");
  108. strcpy(hostname, "FAILURE");
  109.     }
  110.     strncpy(ub->nodename, hostname, sizeof(ub->nodename));
  111.     ub->nodename[_SYS_NMLN - 1] = '';
  112.     return 0;
  113. }
  114. int strcasecmp(const char *s1, const char *s2)
  115. {
  116.     return stricmp(s1, s2);
  117. }
  118. uid_t getuid(void) 
  119.     return 1;
  120.     
  121. }
  122. gid_t getgid(void)
  123. {
  124.     return 0;
  125. }
  126. int gethostid(void)
  127. {
  128.     /*XXX*/
  129.     return 0;
  130. }
  131. __inline int nice(int pri)
  132. {
  133.     return 0;
  134. }
  135. extern void TkWinXInit(HINSTANCE hInstance);
  136. extern int main(int argc, const char *argv[]);
  137. extern int __argc;
  138. extern char **__argv;
  139. static char argv0[255]; /* Buffer used to hold argv0. */
  140. char *__progname = "mash";
  141. void
  142. ShowMessage(int level, char *msg)
  143. {
  144.     MessageBeep(level);
  145.     MessageBox(NULL, msg, __progname,
  146.        level | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
  147. }
  148. int SetupConsole()
  149. {
  150.     /*
  151.      * stuff from knowledge base Q105305 (see that for details)
  152.      * open a console and do the work around to get the console to work in all
  153.      * cases
  154.      */
  155.     int hCrt;
  156.     FILE *hf=0;
  157.     const COORD screenSz = {80, 5000}; /* size of console buffer */
  158.     AllocConsole();
  159.     hf=0;
  160.     hCrt = _open_osfhandle(
  161.             (long)GetStdHandle(STD_OUTPUT_HANDLE), _O_TEXT);
  162.     if (hCrt!=-1) hf = _fdopen(hCrt, "w");
  163.     if (hf!=0) *stdout = *hf;
  164.     if (hCrt==-1 || hf==0 || 0!=setvbuf(stdout, NULL, _IONBF, 0)) {
  165.             ShowMessage(MB_ICONINFORMATION,
  166.                         "unable to mount reroute stdout");
  167.             return FALSE;
  168.     }
  169.     SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), screenSz);
  170.     hf=0;
  171.     hCrt = _open_osfhandle(
  172.         (long)GetStdHandle(STD_ERROR_HANDLE), _O_TEXT);
  173.     if (hCrt!=-1) hf = _fdopen(hCrt, "w");
  174.     if (hf!=0) *stderr = *hf;
  175.     if (hCrt==-1 || hf==0 || 0!=setvbuf(stderr, NULL, _IONBF, 0)) {
  176.             ShowMessage(MB_ICONINFORMATION,
  177.                         "reroute stderr failed in SetupConsole");
  178.             return FALSE;
  179.     }
  180.     hf=0;
  181.     hCrt = _open_osfhandle((long)GetStdHandle(STD_INPUT_HANDLE), _O_TEXT);
  182.     if (hCrt!=-1) hf = _fdopen(hCrt, "r");
  183.     if (hf!=0) *stdin = *hf;
  184.     if (hCrt==-1 || hf==0 || 0!=setvbuf(stdin, NULL, _IONBF, 0)) {
  185.             ShowMessage(MB_ICONINFORMATION,
  186.                         "reroute stdin failed in SetupConsole");
  187.             return FALSE;
  188.     }
  189.     return TRUE;
  190. }
  191.      
  192. int APIENTRY
  193. WinMain(
  194.     HINSTANCE hInstance,
  195.     HINSTANCE hPrevInstance,
  196.     LPSTR lpszCmdLine,
  197.     int nCmdShow)
  198. {
  199.     char *p;
  200.     WSADATA WSAdata;
  201.     int retcode;
  202.     setlocale(LC_ALL, "C");
  203.     /* XXX
  204.      * initialize our socket interface plus the tcl 7.5 socket
  205.      * interface (since they redefine some routines we call).
  206.      * eventually we should just call the tcl sockets but at
  207.      * the moment that's hard to set up since they only support
  208.      * tcp in the notifier.
  209.      */
  210.     if (WSAStartup(MAKEWORD (1, 1), &WSAdata)) {
  211.      perror("Windows Sockets init failed");
  212. abort();
  213.     }
  214. /*    TclHasSockets(NULL);
  215.     TkWinXInit(hInstance); */
  216.     /*
  217.      * Increase the application queue size from default value of 8.
  218.      * At the default value, cross application SendMessage of WM_KILLFOCUS
  219.      * will fail because the handler will not be able to do a PostMessage!
  220.      * This is only needed for Windows 3.x, since NT dynamically expands
  221.      * the queue.
  222.      */
  223.     SetMessageQueue(64);
  224.     GetModuleFileName(NULL, argv0, 255);
  225.     p = argv0;
  226.     __progname = strrchr(p, '/');
  227.     if (__progname != NULL) {
  228. __progname++;
  229.     }
  230.     else {
  231. __progname = strrchr(p, '\');
  232. if (__progname != NULL) {
  233.     __progname++;
  234. } else {
  235.     __progname = p;
  236. }
  237.     }
  238.     if (__argc>1) {            
  239.             SetupConsole();
  240.     }
  241.     retcode=main(__argc, (const char**)__argv);
  242.     if (retcode!=0) {
  243.             assert(FALSE);      /* don't die without letting user know why */
  244.     }
  245.     return retcode;
  246. }
  247. #if 0
  248. static char szTemp[4096];
  249. int
  250. printf(const char *fmt, ...)
  251. {
  252.     int retval;
  253.     
  254.     va_list ap;
  255.     va_start (ap, fmt);
  256.     retval = vsprintf(szTemp, fmt, ap);
  257.     OutputDebugString(szTemp);
  258.     ShowMessage(MB_ICONINFORMATION, szTemp);
  259.     va_end (ap);
  260.     return(retval);
  261. }
  262. int
  263. fprintf(FILE *f, const char *fmt, ...)
  264. {
  265.     int retval;
  266.     
  267.     va_list ap;
  268.     va_start (ap, fmt);
  269.     if (f == stderr) {
  270. retval = vsprintf(szTemp, fmt, ap);
  271. OutputDebugString(szTemp);
  272. ShowMessage(MB_ICONERROR, szTemp);
  273. va_end (ap);
  274.     }
  275.     else
  276. retval = vfprintf(f, fmt, ap);
  277.     
  278.     return(retval);
  279. }
  280. void
  281. perror(const char *msg)
  282. {
  283.     DWORD cMsgLen;
  284.     CHAR *msgBuf;
  285.     DWORD dwError = GetLastError();
  286.     
  287.     cMsgLen = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
  288.     FORMAT_MESSAGE_ALLOCATE_BUFFER | 40, NULL,
  289.     dwError,
  290.     MAKELANGID(0, SUBLANG_ENGLISH_US),
  291.     (LPTSTR) &msgBuf, 512,
  292.     NULL);
  293.     if (!cMsgLen)
  294. fprintf(stderr, "%s%sError code %lun",
  295. msg?msg:"", msg?": ":"", dwError);
  296.     else {
  297. fprintf(stderr, "%s%s%sn", msg?msg:"", msg?": ":"", msgBuf);
  298. LocalFree((HLOCAL)msgBuf);
  299.     }
  300. }
  301. int
  302. WinPutsCmd(clientData, interp, argc, argv)
  303.     ClientData clientData; /* ConsoleInfo pointer. */
  304.     Tcl_Interp *interp; /* Current interpreter. */
  305.     int argc; /* Number of arguments. */
  306.     char **argv; /* Argument strings. */
  307. {
  308.     int i, newline;
  309.     char *fileId;
  310.     i = 1;
  311.     newline = 1;
  312.     if ((argc >= 2) && (strcmp(argv[1], "-nonewline") == 0)) {
  313. newline = 0;
  314. i++;
  315.     }
  316.     if ((i < (argc-3)) || (i >= argc)) {
  317. Tcl_AppendResult(interp, "wrong # args: should be "", argv[0],
  318. " ?-nonewline? ?fileId? string"", (char *) NULL);
  319. return TCL_ERROR;
  320.     }
  321.     /*
  322.      * The code below provides backwards compatibility with an old
  323.      * form of the command that is no longer recommended or documented.
  324.      */
  325.     if (i == (argc-3)) {
  326. if (strncmp(argv[i+2], "nonewline", strlen(argv[i+2])) != 0) {
  327.     Tcl_AppendResult(interp, "bad argument "", argv[i+2],
  328.     "": should be "nonewline"", (char *) NULL);
  329.     return TCL_ERROR;
  330. }
  331. newline = 0;
  332.     }
  333.     if (i == (argc-1)) {
  334. fileId = "stdout";
  335.     } else {
  336. fileId = argv[i];
  337. i++;
  338.     }
  339.     if (strcmp(fileId, "stdout") == 0 || strcmp(fileId, "stderr") == 0) {
  340. char *result;
  341. int level;
  342. if (newline) {
  343.     int len = strlen(argv[i]);
  344.     result = ckalloc(len+2);
  345.     memcpy(result, argv[i], len);
  346.     result[len] = 'n';
  347.     result[len+1] = 0;
  348. } else {
  349.     result = argv[i];
  350. }
  351. if (strcmp(fileId, "stdout") == 0) {
  352.     level = MB_ICONINFORMATION;
  353. } else {
  354.     level = MB_ICONERROR;
  355. }
  356. OutputDebugString(result);
  357. ShowMessage(level, result);
  358. if (newline)
  359.     ckfree(result);
  360. return TCL_OK;
  361.     } else {
  362. extern int Tcl_PutsCmd(ClientData clientData, Tcl_Interp *interp,
  363.        int argc, char **argv);
  364. return (Tcl_PutsCmd(clientData, interp, argc, argv));
  365.     }
  366. }
  367. #endif
  368. int
  369. WinGetUserName(clientData, interp, argc, argv)
  370.     ClientData clientData;
  371.     Tcl_Interp *interp; /* Current interpreter. */
  372.     int argc; /* Number of arguments. */
  373.     char *argv[]; /* Argument strings. */
  374. {
  375.     char user[256];
  376.     int size = sizeof(user);
  377.     
  378.     if (!GetUserName(user, &size)) {
  379. Tcl_AppendResult(interp, "GetUserName failed", NULL);
  380. return TCL_ERROR;
  381.     }
  382.     Tcl_AppendResult(interp, user, NULL);
  383.     return TCL_OK;
  384. }
  385. int WinGetHostName(clientData, interp, argc, argv)
  386.                    ClientData clientData;
  387.                    Tcl_Interp *interp; /* Current interpreter. */
  388.                    int argc; /* Number of arguments. */
  389.                    char *argv[]; /* Argument strings. */               
  390. {
  391.         char hostname[MAXGETHOSTSTRUCT];
  392.         if (SOCKET_ERROR == gethostname(hostname, MAXGETHOSTSTRUCT)) {
  393.                 Tcl_AddErrorInfo(interp, "gethostname failed!");
  394.         }
  395.         Tcl_AppendResult(interp, hostname, NULL);
  396.         return TCL_OK;
  397. }
  398. static HKEY
  399. regroot(root)
  400.     char *root;
  401. {
  402.     if (strcasecmp(root, "HKEY_LOCAL_MACHINE") == 0)
  403. return HKEY_LOCAL_MACHINE;
  404.     else if (strcasecmp(root, "HKEY_CURRENT_USER") == 0)
  405. return HKEY_CURRENT_USER;
  406.     else if (strcasecmp(root, "HKEY_USERS") == 0)
  407. return HKEY_USERS;
  408.     else if (strcasecmp(root, "HKEY_CLASSES_ROOT") == 0)
  409. return HKEY_CLASSES_ROOT;
  410.     else
  411. return NULL;
  412. }
  413. int
  414. WinGetRegistry(clientData, interp, argc, argv)
  415.     ClientData clientData;
  416.     Tcl_Interp *interp; /* Current interpreter. */
  417.     int argc; /* Number of arguments. */
  418.     char **argv; /* Argument strings. */
  419. {
  420.     HKEY hKey, hRootKey;
  421.     DWORD dwType;
  422.     DWORD len, retCode;
  423.     CHAR *regRoot, *regPath, *keyValue, *keyData;
  424.     int retval = TCL_ERROR;
  425.     
  426.     if (argc != 3) {
  427. Tcl_AppendResult(interp, "wrong # args: should be "", argv[0],
  428. "key value"", (char *) NULL);
  429. return TCL_ERROR;
  430.     }
  431.     regRoot = argv[1];
  432.     keyValue = argv[2];
  433.     regPath = strchr(regRoot, '\');
  434.     *regPath++ = '';
  435.     
  436.     if ((hRootKey = regroot(regRoot)) == NULL) {
  437. Tcl_AppendResult(interp, "Unknown registry root "",
  438.  regRoot, """, NULL);
  439. return (TCL_ERROR);
  440.     }
  441.     
  442.     retCode = RegOpenKeyEx(hRootKey, regPath, 0,
  443.    KEY_READ, &hKey);
  444.     if (retCode == ERROR_SUCCESS) {
  445. retCode = RegQueryValueEx(hKey, keyValue, NULL, &dwType,
  446.   NULL, &len);
  447. if (retCode == ERROR_SUCCESS &&
  448.     dwType == REG_SZ && len) {
  449.     keyData = (CHAR *) ckalloc(len);
  450.     retCode = RegQueryValueEx(hKey, keyValue, NULL, NULL,
  451.       keyData, &len);
  452.     if (retCode == ERROR_SUCCESS) {
  453. Tcl_AppendResult(interp, keyData, NULL);
  454. free(keyData);
  455. retval = TCL_OK;
  456.     }
  457. }
  458. RegCloseKey(hKey);
  459.     }
  460.     if (retval == TCL_ERROR) {
  461. Tcl_AppendResult(interp, "Cannot find registry entry "", regRoot,
  462.  "\", regPath, "\", keyValue, """, NULL);
  463.     }
  464.     return (retval);
  465. }
  466. int
  467. WinPutRegistry(clientData, interp, argc, argv)
  468.     ClientData clientData;
  469.     Tcl_Interp *interp; /* Current interpreter. */
  470.     int argc; /* Number of arguments. */
  471.     char **argv; /* Argument strings. */
  472. {
  473.     HKEY hKey, hRootKey;
  474.     DWORD retCode;
  475.     CHAR *regRoot, *regPath, *keyValue, *keyData;
  476.     DWORD new;
  477.     int result = TCL_OK;
  478.     
  479.     if (argc != 4) {
  480. Tcl_AppendResult(interp, "wrong # args: should be "", argv[0],
  481. "key value data"", (char *) NULL);
  482. return TCL_ERROR;
  483.     }
  484.     regRoot = argv[1];
  485.     keyValue = argv[2];
  486.     keyData = argv[3];
  487.     
  488.     regPath = strchr(regRoot, '\');
  489.     *regPath++ = '';
  490.     
  491.     if ((hRootKey = regroot(regRoot)) == NULL) {
  492. Tcl_AppendResult(interp, "Unknown registry root "",
  493.  regRoot, """, NULL);
  494. return (TCL_ERROR);
  495.     }
  496.     retCode = RegCreateKeyEx(hRootKey, regPath, 0,
  497.      "",
  498.      REG_OPTION_NON_VOLATILE,
  499.      KEY_ALL_ACCESS,
  500.      NULL,
  501.      &hKey, &new);
  502.     if (retCode == ERROR_SUCCESS) {
  503. retCode = RegSetValueEx(hKey, keyValue, 0, REG_SZ, keyData, strlen(keyData));
  504. if (retCode != ERROR_SUCCESS) {
  505.     Tcl_AppendResult(interp, "unable to set key "", regRoot, "\",
  506.      regPath, "" with value "", keyValue, """,
  507.      (char *) NULL);
  508.     result = TCL_ERROR;
  509. }
  510. RegCloseKey(hKey);
  511.     }
  512.     else {
  513. Tcl_AppendResult(interp, "unable to create key "", regRoot, "\",
  514.  regPath, """, (char *) NULL);
  515. result = TCL_ERROR;
  516.     }
  517.     return (result);
  518. }
  519. int platformInit(Tcl_Interp* interp)
  520. {
  521.         /* tcl.CreateCommand("puts", WinPutsCmd, (ClientData)0); */
  522.         Tcl_CreateCommand(interp, "getusername", WinGetUserName,
  523.                           (ClientData)0, (Tcl_CmdDeleteProc*)0);
  524.         Tcl_CreateCommand(interp, "gethostname", WinGetHostName,
  525.                           (ClientData)0, (Tcl_CmdDeleteProc*)0);
  526.         Tcl_CreateCommand(interp, "putregistry", WinPutRegistry,
  527.                           (ClientData)0, (Tcl_CmdDeleteProc*)0);
  528.         Tcl_CreateCommand(interp, "getregistry", WinGetRegistry,
  529.                           (ClientData)0, (Tcl_CmdDeleteProc*)0);
  530.         
  531. #ifndef NO_TK
  532.         /*
  533.          * Initialize the console only if we are running as an interactive
  534.          * application.
  535.          */    
  536.         if (0==strcmp(Tcl_GetVar(interp, "tcl_interactive",
  537.                                  TCL_GLOBAL_ONLY), "1")) {
  538.                 /*
  539.                  * Create the console channels and install them as the standard
  540.                  * channels.  All I/O will be discarded until TkConsoleInit is
  541.                  * called to attach the console to a text widget.
  542.                  */            
  543.                 TkConsoleCreate();
  544.                 if (TkConsoleInit(interp) == TCL_ERROR) {
  545.                         fprintf(stderr, "error calling TkConsoleInitn");
  546.                 }
  547.         }
  548. #endif
  549.         return TCL_OK;
  550. }
  551. #endif
  552. static const char ISO_C_forbids_an_empty_source_file; /* don't know why ... */