NewAPIs.h
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:16k
源码类别:

模拟服务器

开发平台:

C/C++

  1. /*
  2.  *  Copyright (c) 1997-1999, Microsoft Corporation
  3.  *
  4.  *  Wrapper module that "stubs" APIs that were not implemented
  5.  *  on Windows 95 or Windows NT versions less than 4.0 SP 3.
  6.  *
  7.  *  By using this header, your code will run on older platforms.
  8.  *
  9.  *  To enable a particular wrapper, define the corresponding symbol.
  10.  *
  11.  *  Function                Symbol
  12.  *
  13.  *  GetDiskFreeSpaceEx      WANT_GETDISKFREESPACEEX_WRAPPER
  14.  *  GetLongPathName         WANT_GETLONGPATHNAME_WRAPPER
  15.  *  GetFileAttributesEx     WANT_GETFILEATTRIBUTESEX_WRAPPER
  16.  *  IsDebuggerPresent       WANT_ISDEBUGGERPRESENT_WRAPPER
  17.  *
  18.  *  Exactly one source file must include the line
  19.  *
  20.  *  #define COMPILE_NEWAPIS_STUBS
  21.  *
  22.  *  before including this file.
  23.  *
  24.  */
  25. #ifdef __cplusplus
  26. extern "C" {            /* Assume C declarations for C++ */
  27. #endif  /* __cplusplus */
  28. /*****************************************************************************
  29.  *
  30.  * GetDiskFreeSpaceEx
  31.  *
  32.  *****************************************************************************/
  33. #ifdef WANT_GETDISKFREESPACEEX_WRAPPER
  34. #undef GetDiskFreeSpaceEx
  35. #define GetDiskFreeSpaceEx _GetDiskFreeSpaceEx
  36. extern BOOL (CALLBACK *GetDiskFreeSpaceEx)
  37.              (LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER);
  38. /*
  39.  * Exactly one file should define this symbol.
  40.  */
  41. #ifdef COMPILE_NEWAPIS_STUBS
  42. /*
  43.  * The version to use if we are forced to emulate.
  44.  */
  45. static BOOL WINAPI
  46. Emulate_GetDiskFreeSpaceEx(LPCTSTR ptszRoot, PULARGE_INTEGER pliQuota,
  47.                          PULARGE_INTEGER pliTotal, PULARGE_INTEGER pliFree)
  48. {
  49.     DWORD dwSecPerClus, dwBytesPerSec, dwFreeClus, dwTotalClus;
  50.     BOOL fRc;
  51.     fRc = GetDiskFreeSpace(ptszRoot, &dwSecPerClus, &dwBytesPerSec,
  52.                            &dwFreeClus, &dwTotalClus);
  53.     if (fRc) {
  54.         DWORD dwBytesPerClus = dwSecPerClus * dwBytesPerSec;
  55.         /*
  56.          *  Curiously, of all the output parameters, only pliFree is
  57.          *  allowed to be NULL.
  58.          */
  59.         *(__int64 *)pliQuota = Int32x32To64(dwBytesPerClus, dwFreeClus);
  60.         if (pliFree) {
  61.             *pliFree = *pliQuota;
  62.         }
  63.         *(__int64 *)pliTotal = Int32x32To64(dwBytesPerClus, dwTotalClus);
  64.     }
  65.     return fRc;
  66. }
  67. /*
  68.  * The stub that probes to decide which version to use.
  69.  */
  70. static BOOL WINAPI
  71. Probe_GetDiskFreeSpaceEx(LPCTSTR ptszRoot, PULARGE_INTEGER pliQuota,
  72.                          PULARGE_INTEGER pliTotal, PULARGE_INTEGER pliFree)
  73. {
  74.     HINSTANCE hinst;
  75.     FARPROC fp;
  76.     BOOL fRc;
  77.     BOOL (CALLBACK *RealGetDiskFreeSpaceEx)
  78.              (LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER);
  79.     hinst = GetModuleHandle(TEXT("KERNEL32"));
  80. #ifdef UNICODE
  81.     fp = GetProcAddress(hinst, "GetDiskFreeSpaceExW");
  82. #else
  83.     fp = GetProcAddress(hinst, "GetDiskFreeSpaceExA");
  84. #endif
  85.     if (fp) {
  86.         *(FARPROC *)&RealGetDiskFreeSpaceEx = fp;
  87.         fRc = RealGetDiskFreeSpaceEx(ptszRoot, pliQuota, pliTotal, pliFree);
  88.         if (fRc || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) {
  89.             GetDiskFreeSpaceEx = RealGetDiskFreeSpaceEx;
  90.         } else {
  91.             GetDiskFreeSpaceEx = Emulate_GetDiskFreeSpaceEx;
  92.             fRc = GetDiskFreeSpaceEx(ptszRoot, pliQuota, pliTotal, pliFree);
  93.         }
  94.     } else {
  95.         GetDiskFreeSpaceEx = Emulate_GetDiskFreeSpaceEx;
  96.         fRc = GetDiskFreeSpaceEx(ptszRoot, pliQuota, pliTotal, pliFree);
  97.     }
  98.     return fRc;
  99. }
  100. BOOL (CALLBACK *GetDiskFreeSpaceEx)
  101.              (LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER) =
  102.                 Probe_GetDiskFreeSpaceEx;
  103. #endif /* COMPILE_NEWAPIS_STUBS */
  104. #endif /* WANT_GETDISKFREESPACEEX_WRAPPER */
  105. /*****************************************************************************
  106.  *
  107.  * GetLongPathName
  108.  *
  109.  *****************************************************************************/
  110. #ifdef WANT_GETLONGPATHNAME_WRAPPER
  111. #include <shlobj.h>
  112. #undef GetLongPathName
  113. #define GetLongPathName _GetLongPathName
  114. extern DWORD (CALLBACK *GetLongPathName)(LPCTSTR, LPTSTR, DWORD);
  115. /*
  116.  * Exactly one file should define this symbol.
  117.  */
  118. #ifdef COMPILE_NEWAPIS_STUBS
  119. /*
  120.  * The version to use if we are forced to emulate.
  121.  */
  122. static DWORD WINAPI
  123. Emulate_GetLongPathName(LPCTSTR ptszShort, LPTSTR ptszLong, DWORD ctchBuf)
  124. {
  125.     LPSHELLFOLDER psfDesk;
  126.     HRESULT hr;
  127.     LPITEMIDLIST pidl;
  128.     TCHAR tsz[MAX_PATH];            /* Scratch TCHAR buffer */
  129.     DWORD dwRc;
  130.     LPMALLOC pMalloc;
  131.     /*
  132.      *  The file had better exist.  GetFileAttributes() will
  133.      *  not only tell us, but it'll even call SetLastError()
  134.      *  for us.
  135.      */
  136.     if (GetFileAttributes(ptszShort) == 0xFFFFFFFF) {
  137.         return 0;
  138.     }
  139.     /*
  140.      *  First convert from relative path to absolute path.
  141.      *  This uses the scratch TCHAR buffer.
  142.      */
  143.     dwRc = GetFullPathName(ptszShort, MAX_PATH, tsz, NULL);
  144.     if (dwRc == 0) {
  145.         /*
  146.          *  Failed; GFPN already did SetLastError().
  147.          */
  148.     } else if (dwRc >= MAX_PATH) {
  149.         /*
  150.          *  Resulting path would be too long.
  151.          */
  152.         SetLastError(ERROR_BUFFER_OVERFLOW);
  153.         dwRc = 0;
  154.     } else {
  155.         /*
  156.          *  Just right.
  157.          */
  158.         hr = SHGetDesktopFolder(&psfDesk);
  159.         if (SUCCEEDED(hr)) {
  160.             ULONG cwchEaten;
  161. #ifdef UNICODE
  162. #ifdef __cplusplus
  163.             hr = psfDesk->ParseDisplayName(NULL, NULL, tsz,
  164.                                        &cwchEaten, &pidl, NULL);
  165. #else
  166.             hr = psfDesk->lpVtbl->ParseDisplayName(psfDesk, NULL, NULL, tsz,
  167.                                        &cwchEaten, &pidl, NULL);
  168. #endif
  169. #else
  170.             WCHAR wsz[MAX_PATH];        /* Scratch WCHAR buffer */
  171.             /*
  172.              *  ParseDisplayName requires UNICODE, so we use
  173.              *  the scratch WCHAR buffer during the conversion.
  174.              */
  175.             dwRc = MultiByteToWideChar(
  176.                         AreFileApisANSI() ? CP_ACP : CP_OEMCP,
  177.                         0, tsz, -1, wsz, MAX_PATH);
  178.             if (dwRc == 0) {
  179.                 /*
  180.                  *  Couldn't convert to UNICODE.  MB2WC uses
  181.                  *  ERROR_INSUFFICIENT_BUFFER, which we convert
  182.                  *  to ERROR_BUFFER_OVERFLOW.  Any other error
  183.                  *  we leave alone.
  184.                  */
  185.                 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
  186.                     SetLastError(ERROR_BUFFER_OVERFLOW);
  187.                 }
  188.                 dwRc = 0;
  189.             } else {
  190. #ifdef __cplusplus
  191.                 hr = psfDesk->ParseDisplayName(NULL, NULL, wsz,
  192.                                            &cwchEaten, &pidl, NULL);
  193. #else
  194.                 hr = psfDesk->lpVtbl->ParseDisplayName(psfDesk, NULL, NULL,
  195.                                            wsz, &cwchEaten, &pidl, NULL);
  196. #endif
  197. #endif
  198.                 if (FAILED(hr)) {
  199.                     /*
  200.                      *  Weird.  Convert the result back to a Win32
  201.                      *  error code if we can.  Otherwise, use the
  202.                      *  generic "duh" error code ERROR_INVALID_DATA.
  203.                      */
  204.                     if (HRESULT_FACILITY(hr) == FACILITY_WIN32) {
  205.                         SetLastError(HRESULT_CODE(hr));
  206.                     } else {
  207.                         SetLastError(ERROR_INVALID_DATA);
  208.                     }
  209.                     dwRc = 0;
  210.                 } else {
  211.                     /*
  212.                      *  Convert the pidl back to a filename in the
  213.                      *  TCHAR scratch buffer.
  214.                      */
  215.                     dwRc = SHGetPathFromIDList(pidl, tsz);
  216.                     if (dwRc == 0 && tsz[0]) {
  217.                         /*
  218.                          *  Bizarre failure.
  219.                          */
  220.                         SetLastError(ERROR_INVALID_DATA);
  221.                     } else {
  222.                         /*
  223.                          *  Copy the result back to the user's buffer.
  224.                          */
  225.                         dwRc = lstrlen(tsz);
  226.                         if (dwRc + 1 > ctchBuf) {
  227.                             /*
  228.                              *  On buffer overflow, return necessary
  229.                              *  size including terminating null (+1).
  230.                              */
  231.                             SetLastError(ERROR_INSUFFICIENT_BUFFER);
  232.                             dwRc = dwRc + 1;
  233.                         } else {
  234.                             /*
  235.                              *  On buffer okay, return actual size not
  236.                              *  including terminating null.
  237.                              */
  238.                             lstrcpyn(ptszLong, tsz, ctchBuf);
  239.                         }
  240.                     }
  241.                     /*
  242.                      *  Free the pidl.
  243.                      */
  244.                     if (SUCCEEDED(SHGetMalloc(&pMalloc))) {
  245. #ifdef __cplusplus
  246.                         pMalloc->Free(pidl);
  247.                         pMalloc->Release();
  248. #else
  249.                         pMalloc->lpVtbl->Free(pMalloc, pidl);
  250.                         pMalloc->lpVtbl->Release(pMalloc);
  251. #endif
  252.                     }
  253.                 }
  254. #ifndef UNICODE
  255.             }
  256. #endif
  257.             /*
  258.              *  Release the desktop folder now that we no longer
  259.              *  need it.
  260.              */
  261. #ifdef __cplusplus
  262.             psfDesk->Release();
  263. #else
  264.             psfDesk->lpVtbl->Release(psfDesk);
  265. #endif
  266.         }
  267.     }
  268.     return dwRc;
  269. }
  270. /*
  271.  * The stub that probes to decide which version to use.
  272.  */
  273. static DWORD WINAPI
  274. Probe_GetLongPathName(LPCTSTR ptszShort, LPTSTR ptszLong, DWORD ctchBuf)
  275. {
  276.     HINSTANCE hinst;
  277.     FARPROC fp;
  278.     DWORD dwRc;
  279.     BOOL (CALLBACK *RealGetLongPathName)(LPCTSTR, LPTSTR, DWORD);
  280.     hinst = GetModuleHandle(TEXT("KERNEL32"));
  281. #ifdef UNICODE
  282.     fp = GetProcAddress(hinst, "GetLongPathNameW");
  283. #else
  284.     fp = GetProcAddress(hinst, "GetLongPathNameA");
  285. #endif
  286.     if (fp) {
  287.         *(FARPROC *)&RealGetLongPathName = fp;
  288.         dwRc = RealGetLongPathName(ptszShort, ptszLong, ctchBuf);
  289.         if (dwRc || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) {
  290.             GetLongPathName = RealGetLongPathName;
  291.         } else {
  292.             GetLongPathName = Emulate_GetLongPathName;
  293.             dwRc = GetLongPathName(ptszShort, ptszLong, ctchBuf);
  294.         }
  295.     } else {
  296.         GetLongPathName = Emulate_GetLongPathName;
  297.         dwRc = GetLongPathName(ptszShort, ptszLong, ctchBuf);
  298.     }
  299.     return dwRc;
  300. }
  301. DWORD (CALLBACK *GetLongPathName)(LPCTSTR, LPTSTR, DWORD) =
  302.                 Probe_GetLongPathName;
  303. #endif /* COMPILE_NEWAPIS_STUBS */
  304. #endif /* WANT_GETLONGPATHNAME_WRAPPER */
  305. /*****************************************************************************
  306.  *
  307.  * GetFileAttributesEx
  308.  *
  309.  *****************************************************************************/
  310. #ifdef WANT_GETFILEATTRIBUTESEX_WRAPPER
  311. #undef GetFileAttributesEx
  312. #define GetFileAttributesEx _GetFileAttributesEx
  313. /*
  314.  *  Really old header files don't even have definitions for these constants
  315.  *  and structures.
  316.  */
  317. #if WINVER < 0x040A
  318. typedef enum _GET_FILEEX_INFO_LEVELS {
  319.     GetFileExInfoStandard,
  320.     GetFileExMaxInfoLevel
  321. } GET_FILEEX_INFO_LEVELS;
  322. typedef struct _WIN32_FILE_ATTRIBUTE_DATA {
  323.     DWORD dwFileAttributes;
  324.     FILETIME ftCreationTime;
  325.     FILETIME ftLastAccessTime;
  326.     FILETIME ftLastWriteTime;
  327.     DWORD nFileSizeHigh;
  328.     DWORD nFileSizeLow;
  329. } WIN32_FILE_ATTRIBUTE_DATA, *LPWIN32_FILE_ATTRIBUTE_DATA;
  330. #endif
  331. extern BOOL (CALLBACK *GetFileAttributesEx)
  332.                 (LPCTSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
  333. /*
  334.  * Exactly one file should define this symbol.
  335.  */
  336. #ifdef COMPILE_NEWAPIS_STUBS
  337. /*
  338.  * The version to use if we are forced to emulate.
  339.  */
  340. static BOOL WINAPI
  341. Emulate_GetFileAttributesEx(LPCTSTR ptszFile, GET_FILEEX_INFO_LEVELS level,
  342.                             LPVOID pv)
  343. {
  344.     BOOL fRc;
  345.     if (level == GetFileExInfoStandard) {
  346.         /*
  347.          *  Must call GetFileAttributes first to avoid returning random
  348.          *  values if the so-called filename contains wildcards.
  349.          */
  350.         if (GetFileAttributes(ptszFile) != 0xFFFFFFFF) {
  351.             HANDLE hfind;
  352.             WIN32_FIND_DATA wfd;
  353.             hfind = FindFirstFile(ptszFile, &wfd);
  354.             if (hfind != INVALID_HANDLE_VALUE) {
  355.                 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
  356.                 FindClose(hfind);
  357.                 pfad->dwFileAttributes = wfd.dwFileAttributes;
  358.                 pfad->ftCreationTime   = wfd.ftCreationTime;
  359.                 pfad->ftLastAccessTime = wfd.ftLastAccessTime;
  360.                 pfad->ftLastWriteTime  = wfd.ftLastWriteTime;
  361.                 pfad->nFileSizeHigh    = wfd.nFileSizeHigh;
  362.                 pfad->nFileSizeLow     = wfd.nFileSizeLow;
  363.                 fRc = TRUE;
  364.             } else {
  365.                 /*
  366.                  *  FindFirstFile already called SetLastError() for us.
  367.                  */
  368.                 fRc = FALSE;
  369.             }
  370.         } else {
  371.             /*
  372.              *  GetFileAttributes already called SetLastError() for us.
  373.              */
  374.             fRc = FALSE;
  375.         }
  376.     } else {
  377.         /*
  378.          *  Unknown info level.
  379.          */
  380.         SetLastError(ERROR_INVALID_PARAMETER);
  381.         fRc = FALSE;
  382.     }
  383.     return fRc;
  384. }
  385. /*
  386.  * The stub that probes to decide which version to use.
  387.  */
  388. static BOOL WINAPI
  389. Probe_GetFileAttributesEx(LPCTSTR ptszFile, GET_FILEEX_INFO_LEVELS level,
  390.                           LPVOID pv)
  391. {
  392.     HINSTANCE hinst;
  393.     FARPROC fp;
  394.     BOOL fRc;
  395.     BOOL (CALLBACK *RealGetFileAttributesEx)
  396.              (LPCTSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
  397.     hinst = GetModuleHandle(TEXT("KERNEL32"));
  398. #ifdef UNICODE
  399.     fp = GetProcAddress(hinst, "GetFileAttributesExW");
  400. #else
  401.     fp = GetProcAddress(hinst, "GetFileAttributesExA");
  402. #endif
  403.     if (fp) {
  404.         *(FARPROC *)&RealGetFileAttributesEx = fp;
  405.         fRc = RealGetFileAttributesEx(ptszFile, level, pv);
  406.         if (fRc || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) {
  407.             GetFileAttributesEx = RealGetFileAttributesEx;
  408.         } else {
  409.             GetFileAttributesEx = Emulate_GetFileAttributesEx;
  410.             fRc = GetFileAttributesEx(ptszFile, level, pv);
  411.         }
  412.     } else {
  413.         GetFileAttributesEx = Emulate_GetFileAttributesEx;
  414.         fRc = GetFileAttributesEx(ptszFile, level, pv);
  415.     }
  416.     return fRc;
  417. }
  418. BOOL (CALLBACK *GetFileAttributesEx)
  419.                 (LPCTSTR, GET_FILEEX_INFO_LEVELS, LPVOID) =
  420.         Probe_GetFileAttributesEx;
  421. #endif /* COMPILE_NEWAPIS_STUBS */
  422. #endif /* WANT_GETFILEATTRIBUTESEX_WRAPPER */
  423. /*****************************************************************************
  424.  *
  425.  * IsDebuggerPresent
  426.  *
  427.  *****************************************************************************/
  428. #ifdef WANT_ISDEBUGGERPRESENT_WRAPPER
  429. #define IsDebuggerPresent _IsDebuggerPresent
  430. extern BOOL (CALLBACK *IsDebuggerPresent)(VOID);
  431. /*
  432.  * Exactly one file should define this symbol.
  433.  */
  434. #ifdef COMPILE_NEWAPIS_STUBS
  435. /*
  436.  * The version to use if we are forced to emulate.
  437.  */
  438. static BOOL WINAPI
  439. Emulate_IsDebuggerPresent(VOID)
  440. {
  441.     /* No way to tell, so just say "no". */
  442.     return FALSE;
  443. }
  444. /*
  445.  * The stub that probes to decide which version to use.
  446.  */
  447. static BOOL WINAPI
  448. Probe_IsDebuggerPresent(VOID)
  449. {
  450.     HINSTANCE hinst;
  451.     FARPROC fp;
  452.     BOOL (CALLBACK *RealIsDebuggerPresent)(VOID);
  453.     hinst = GetModuleHandle(TEXT("KERNEL32"));
  454.     fp = GetProcAddress(hinst, "IsDebuggerPresent");
  455.     if (fp) {
  456.         *(FARPROC *)&IsDebuggerPresent = fp;
  457.     } else {
  458.         IsDebuggerPresent = Emulate_IsDebuggerPresent;
  459.     }
  460.     return IsDebuggerPresent();
  461. }
  462. BOOL (CALLBACK *IsDebuggerPresent)(VOID) =
  463.         Probe_IsDebuggerPresent;
  464. #endif /* COMPILE_NEWAPIS_STUBS */
  465. #endif /* WANT_ISDEBUGGERPRESENT_WRAPPER */
  466. #ifdef __cplusplus
  467. }
  468. #endif    /* __cplusplus */