NewAPIs.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543
  1. /*
  2. * Copyright (c) 1997-2004, 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. DWORD (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 */