Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

709 lines
19 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. EmulateCDFS.cpp
  5. Abstract:
  6. Removes read only attributes from CD directories: just like Win9x.
  7. This shim has gone through several revisions. Originally it was thought
  8. that win9x simply ignored the ReadOnly, DesiredAccess and ShareMode
  9. parameters, but after some testing, it turns out that this is only true
  10. for the CDRom drive.
  11. Unfortunately we have to check every file to see if it's on the CD first,
  12. just in case someone opens with exclusive access and then tries to open
  13. again.
  14. Notes:
  15. This is a general purpose shim.
  16. History:
  17. 01/03/2000 a-jamd Created
  18. 12/02/2000 linstev Separated into 2 shims: RemoveReadOnlyAttribute and this one
  19. Added CreateFile hooks
  20. --*/
  21. #include "precomp.h"
  22. #include "CharVector.h"
  23. IMPLEMENT_SHIM_BEGIN(EmulateCDFS)
  24. #include "ShimHookMacro.h"
  25. APIHOOK_ENUM_BEGIN
  26. APIHOOK_ENUM_ENTRY(OpenFile)
  27. APIHOOK_ENUM_ENTRY(CreateFileA)
  28. APIHOOK_ENUM_ENTRY(CreateFileW)
  29. APIHOOK_ENUM_ENTRY(CreateFileMappingA)
  30. APIHOOK_ENUM_ENTRY(MapViewOfFile)
  31. APIHOOK_ENUM_ENTRY(MapViewOfFileEx)
  32. APIHOOK_ENUM_ENTRY(DuplicateHandle)
  33. APIHOOK_ENUM_ENTRY(CloseHandle)
  34. APIHOOK_ENUM_ENTRY(GetFileAttributesW)
  35. APIHOOK_ENUM_ENTRY(GetFileAttributesA)
  36. APIHOOK_ENUM_ENTRY(FindFirstFileW)
  37. APIHOOK_ENUM_ENTRY(FindFirstFileA)
  38. APIHOOK_ENUM_ENTRY(FindNextFileW)
  39. APIHOOK_ENUM_ENTRY(FindNextFileA)
  40. APIHOOK_ENUM_ENTRY(GetFileInformationByHandle)
  41. APIHOOK_ENUM_ENTRY(GetDiskFreeSpaceA)
  42. APIHOOK_ENUM_END
  43. typedef struct _FINDFILE_HANDLE
  44. {
  45. HANDLE DirectoryHandle;
  46. PVOID FindBufferBase;
  47. PVOID FindBufferNext;
  48. ULONG FindBufferLength;
  49. ULONG FindBufferValidLength;
  50. RTL_CRITICAL_SECTION FindBufferLock;
  51. } FINDFILE_HANDLE, *PFINDFILE_HANDLE;
  52. class RO_FileMappingList
  53. {
  54. private:
  55. VectorT<HANDLE> hROHandles; // File mapping handles that we have forced to Read only
  56. mutable CRITICAL_SECTION critSec;
  57. inline int GetIndex(HANDLE handle) const;
  58. public:
  59. RO_FileMappingList();
  60. ~RO_FileMappingList();
  61. void Add(HANDLE roHandle);
  62. void Remove(HANDLE roHandle);
  63. BOOL Exist(HANDLE handle) const;
  64. };
  65. RO_FileMappingList::RO_FileMappingList()
  66. {
  67. InitializeCriticalSection(&critSec);
  68. }
  69. RO_FileMappingList::~RO_FileMappingList()
  70. {
  71. DeleteCriticalSection(&critSec);
  72. }
  73. void RO_FileMappingList::Add(HANDLE roHandle)
  74. {
  75. if (roHandle != NULL)
  76. {
  77. EnterCriticalSection(&critSec);
  78. int index = GetIndex(roHandle);
  79. if (index == -1) // not found
  80. {
  81. DPFN(eDbgLevelSpew, "[RO_FileMappingList::Add] Handle 0x%08x", roHandle);
  82. hROHandles.Append(roHandle);
  83. }
  84. LeaveCriticalSection(&critSec);
  85. }
  86. }
  87. void RO_FileMappingList::Remove(HANDLE roHandle)
  88. {
  89. if (roHandle != NULL)
  90. {
  91. EnterCriticalSection(&critSec);
  92. int index = GetIndex(roHandle);
  93. if (index >= 0) // found it
  94. {
  95. DPFN(eDbgLevelSpew, "[RO_FileMappingList::Remove] Handle 0x%08x", roHandle);
  96. hROHandles.Remove(index);
  97. }
  98. LeaveCriticalSection(&critSec);
  99. }
  100. }
  101. inline int RO_FileMappingList::GetIndex(HANDLE handle) const
  102. {
  103. int index = hROHandles.Find(handle);
  104. return index;
  105. }
  106. BOOL RO_FileMappingList::Exist(HANDLE handle) const
  107. {
  108. EnterCriticalSection(&critSec);
  109. BOOL bExist = GetIndex(handle) >= 0;
  110. LeaveCriticalSection(&critSec);
  111. return bExist;
  112. }
  113. // A global list of file mapping handles that we have forced to readonly
  114. RO_FileMappingList *g_RO_Handles = NULL;
  115. /*++
  116. Remove write attributes for read-only devices.
  117. --*/
  118. HFILE
  119. APIHOOK(OpenFile)(
  120. LPCSTR lpFileName, // file name
  121. LPOFSTRUCT lpReOpenBuff, // file information
  122. UINT uStyle // action and attributes
  123. )
  124. {
  125. if ((uStyle & OF_READWRITE) && IsOnCDRomA(lpFileName))
  126. {
  127. // Remove the Read/Write bits
  128. uStyle &= ~OF_READWRITE;
  129. uStyle |= OF_READ;
  130. LOGN(eDbgLevelInfo, "[OpenFile] \"%s\": attributes modified for read-only device", lpFileName);
  131. }
  132. HFILE returnValue = ORIGINAL_API(OpenFile)(lpFileName, lpReOpenBuff, uStyle);
  133. return returnValue;
  134. }
  135. /*++
  136. Remove write attributes for read-only devices.
  137. --*/
  138. HANDLE
  139. APIHOOK(CreateFileA)(
  140. LPSTR lpFileName,
  141. DWORD dwDesiredAccess,
  142. DWORD dwShareMode,
  143. LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  144. DWORD dwCreationDisposition,
  145. DWORD dwFlagsAndAttributes,
  146. HANDLE hTemplateFile
  147. )
  148. {
  149. if (((dwCreationDisposition == OPEN_EXISTING) ||
  150. (dwCreationDisposition == OPEN_ALWAYS)) &&
  151. ((dwDesiredAccess & GENERIC_WRITE) ||
  152. (dwShareMode != FILE_SHARE_READ)) &&
  153. IsOnCDRomA(lpFileName))
  154. {
  155. dwDesiredAccess &= ~GENERIC_WRITE;
  156. dwShareMode = FILE_SHARE_READ;
  157. LOGN(eDbgLevelInfo, "[CreateFileA] \"%s\": attributes modified for read-only device", lpFileName);
  158. }
  159. if (dwFlagsAndAttributes & FILE_FLAG_NO_BUFFERING)
  160. {
  161. dwFlagsAndAttributes &= ~FILE_FLAG_NO_BUFFERING;
  162. LOGN(eDbgLevelInfo, "[CreateFileA] \"%s\": removed NO_BUFFERING flag", lpFileName);
  163. }
  164. HANDLE hRet = ORIGINAL_API(CreateFileA)(
  165. lpFileName,
  166. dwDesiredAccess,
  167. dwShareMode,
  168. lpSecurityAttributes,
  169. dwCreationDisposition,
  170. dwFlagsAndAttributes,
  171. hTemplateFile);
  172. DPFN(eDbgLevelSpew,
  173. "[CreateFileA] -File: \"%s\" -GENERIC_WRITE:%c -FILE_SHARE_WRITE:%c%s",
  174. lpFileName,
  175. (dwDesiredAccess & GENERIC_WRITE) ? 'Y' : 'N',
  176. (dwShareMode & FILE_SHARE_WRITE) ? 'Y' : 'N',
  177. (hRet == INVALID_HANDLE_VALUE) ? "\n\t***********Failed***********" : "");
  178. return hRet;
  179. }
  180. /*++
  181. Remove write attributes for read-only devices.
  182. --*/
  183. HANDLE
  184. APIHOOK(CreateFileW)(
  185. LPWSTR lpFileName,
  186. DWORD dwDesiredAccess,
  187. DWORD dwShareMode,
  188. LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  189. DWORD dwCreationDisposition,
  190. DWORD dwFlagsAndAttributes,
  191. HANDLE hTemplateFile
  192. )
  193. {
  194. if (((dwCreationDisposition == OPEN_EXISTING) ||
  195. (dwCreationDisposition == OPEN_ALWAYS)) &&
  196. ((dwDesiredAccess & GENERIC_WRITE) ||
  197. (dwShareMode != FILE_SHARE_READ)) &&
  198. IsOnCDRomW(lpFileName))
  199. {
  200. dwDesiredAccess &= ~GENERIC_WRITE;
  201. dwShareMode = FILE_SHARE_READ;
  202. LOGN(eDbgLevelError, "[CreateFileW] \"%S\": attributes modified for read-only device", lpFileName);
  203. }
  204. if (dwFlagsAndAttributes & FILE_FLAG_NO_BUFFERING)
  205. {
  206. dwFlagsAndAttributes &= ~FILE_FLAG_NO_BUFFERING;
  207. LOGN(eDbgLevelInfo, "[CreateFileW] \"%S\": removed NO_BUFFERING flag", lpFileName);
  208. }
  209. HANDLE hRet = ORIGINAL_API(CreateFileW)(
  210. lpFileName,
  211. dwDesiredAccess,
  212. dwShareMode,
  213. lpSecurityAttributes,
  214. dwCreationDisposition,
  215. dwFlagsAndAttributes,
  216. hTemplateFile);
  217. DPFN(eDbgLevelSpew,
  218. "[CreateFileW] -File: \"%S\" -GENERIC_WRITE:%c -FILE_SHARE_WRITE:%c%s",
  219. lpFileName,
  220. (dwDesiredAccess & GENERIC_WRITE) ? 'Y' : 'N',
  221. (dwShareMode & FILE_SHARE_WRITE) ? 'Y' : 'N',
  222. (hRet == INVALID_HANDLE_VALUE) ? "\n\t***********Failed***********" : "");
  223. return hRet;
  224. }
  225. HANDLE
  226. APIHOOK(CreateFileMappingA)(
  227. HANDLE hFile, // handle to file
  228. LPSECURITY_ATTRIBUTES lpAttributes, // security
  229. DWORD flProtect, // protection
  230. DWORD dwMaximumSizeHigh, // high-order DWORD of size
  231. DWORD dwMaximumSizeLow, // low-order DWORD of size
  232. LPCSTR lpName // object name
  233. )
  234. {
  235. BOOL bChangedProtect = FALSE;
  236. if (!(flProtect & PAGE_READONLY) && IsOnCDRom(hFile))
  237. {
  238. // This handle is on a CD-ROM, force the protection to READONLY
  239. flProtect = PAGE_READONLY;
  240. bChangedProtect = TRUE;
  241. LOGN(eDbgLevelError, "[CreateFileMappingA] Handle 0x%08x: attributes modified for read-only device", hFile);
  242. }
  243. HANDLE hRet = ORIGINAL_API(CreateFileMappingA)(
  244. hFile,
  245. lpAttributes,
  246. flProtect,
  247. dwMaximumSizeHigh,
  248. dwMaximumSizeLow,
  249. lpName);
  250. // If the handle is on a CD-ROM, rember it
  251. if (bChangedProtect)
  252. {
  253. g_RO_Handles->Add(hRet);
  254. }
  255. DPFN(eDbgLevelSpew,
  256. "[CreateFileMappingA] Handle 0x%08x -PAGE_READWRITE:%c -PAGE_WRITECOPY:%c%s",
  257. lpName,
  258. (flProtect & PAGE_READWRITE) ? 'Y' : 'N',
  259. (flProtect & PAGE_WRITECOPY) ? 'Y' : 'N',
  260. (hRet == INVALID_HANDLE_VALUE) ? "\n\t***********Failed***********" : "");
  261. return hRet;
  262. }
  263. LPVOID
  264. APIHOOK(MapViewOfFile)(
  265. HANDLE hFileMappingObject, // handle to file-mapping object
  266. DWORD dwDesiredAccess, // access mode
  267. DWORD dwFileOffsetHigh, // high-order DWORD of offset
  268. DWORD dwFileOffsetLow, // low-order DWORD of offset
  269. SIZE_T dwNumberOfBytesToMap // number of bytes to map
  270. )
  271. {
  272. //
  273. // Check to see if we need to force Read access for CD-ROM files
  274. // Only the FILE_MAP_READ bit may be enabled for CD-ROM access
  275. //
  276. if ((dwDesiredAccess != FILE_MAP_READ) &&
  277. g_RO_Handles->Exist(hFileMappingObject))
  278. {
  279. dwDesiredAccess = FILE_MAP_READ;
  280. LOGN(eDbgLevelError, "[MapViewOfFile] Handle 0x%08x: attributes modified for read-only device", hFileMappingObject);
  281. }
  282. HANDLE hRet = ORIGINAL_API(MapViewOfFile)(
  283. hFileMappingObject,
  284. dwDesiredAccess,
  285. dwFileOffsetHigh,
  286. dwFileOffsetLow,
  287. dwNumberOfBytesToMap);
  288. return hRet;
  289. }
  290. LPVOID
  291. APIHOOK(MapViewOfFileEx)(
  292. HANDLE hFileMappingObject, // handle to file-mapping object
  293. DWORD dwDesiredAccess, // access mode
  294. DWORD dwFileOffsetHigh, // high-order DWORD of offset
  295. DWORD dwFileOffsetLow, // low-order DWORD of offset
  296. SIZE_T dwNumberOfBytesToMap, // number of bytes to map
  297. LPVOID lpBaseAddress // starting addres
  298. )
  299. {
  300. //
  301. // Check to see if we need to force Read access for CD-ROM files
  302. // Only the FILE_MAP_READ bit may be enabled for CD-ROM access
  303. //
  304. if ((dwDesiredAccess != FILE_MAP_READ) &&
  305. g_RO_Handles->Exist(hFileMappingObject))
  306. {
  307. dwDesiredAccess = FILE_MAP_READ;
  308. LOGN(eDbgLevelError,
  309. "[MapViewOfFile] Handle 0x%08x: attributes modified for read-only device", hFileMappingObject);
  310. }
  311. HANDLE hRet = ORIGINAL_API(MapViewOfFileEx)(
  312. hFileMappingObject,
  313. dwDesiredAccess,
  314. dwFileOffsetHigh,
  315. dwFileOffsetLow,
  316. dwNumberOfBytesToMap,
  317. lpBaseAddress);
  318. return hRet;
  319. }
  320. /*++
  321. If hSourceHandle has been mucked with, add the duplicated handle to our list
  322. --*/
  323. BOOL
  324. APIHOOK(DuplicateHandle)(
  325. HANDLE hSourceProcessHandle, // handle to source process
  326. HANDLE hSourceHandle, // handle to duplicate
  327. HANDLE hTargetProcessHandle, // handle to target process
  328. LPHANDLE lpTargetHandle, // duplicate handle
  329. DWORD dwDesiredAccess, // requested access
  330. BOOL bInheritHandle, // handle inheritance option
  331. DWORD dwOptions // optional actions
  332. )
  333. {
  334. BOOL retval = ORIGINAL_API(DuplicateHandle)(
  335. hSourceProcessHandle,
  336. hSourceHandle,
  337. hTargetProcessHandle,
  338. lpTargetHandle,
  339. dwDesiredAccess,
  340. bInheritHandle,
  341. dwOptions);
  342. if (retval && g_RO_Handles->Exist(hSourceHandle))
  343. {
  344. g_RO_Handles->Add(hTargetProcessHandle);
  345. }
  346. return retval;
  347. }
  348. /*++
  349. If hObject has been mucked with, remove it from the list.
  350. --*/
  351. BOOL
  352. APIHOOK(CloseHandle)(
  353. HANDLE hObject // handle to object
  354. )
  355. {
  356. g_RO_Handles->Remove(hObject);
  357. return ORIGINAL_API(CloseHandle)(hObject);
  358. }
  359. /*++
  360. Remove read only attribute if it's a directory
  361. --*/
  362. DWORD
  363. APIHOOK(GetFileAttributesA)(LPCSTR lpFileName)
  364. {
  365. DWORD dwFileAttributes = ORIGINAL_API(GetFileAttributesA)(lpFileName);
  366. // Check for READONLY and DIRECTORY attributes
  367. if ((dwFileAttributes != INT_PTR(-1)) &&
  368. (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
  369. (dwFileAttributes & FILE_ATTRIBUTE_READONLY) &&
  370. IsOnCDRomA(lpFileName))
  371. {
  372. // Flip the read-only bit.
  373. LOGN(eDbgLevelWarning, "[GetFileAttributesA] Removing FILE_ATTRIBUTE_READONLY");
  374. dwFileAttributes ^= FILE_ATTRIBUTE_READONLY;
  375. }
  376. return dwFileAttributes;
  377. }
  378. /*++
  379. Remove read only attribute if it's a directory
  380. --*/
  381. DWORD
  382. APIHOOK(GetFileAttributesW)(LPCWSTR wcsFileName)
  383. {
  384. DWORD dwFileAttributes = ORIGINAL_API(GetFileAttributesW)(wcsFileName);
  385. // Check for READONLY and DIRECTORY attributes
  386. if ((dwFileAttributes != INT_PTR(-1)) &&
  387. (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
  388. (dwFileAttributes & FILE_ATTRIBUTE_READONLY) &&
  389. IsOnCDRomW(wcsFileName))
  390. {
  391. // Flip the read-only bit.
  392. LOGN(eDbgLevelWarning, "[GetFileAttributesW] Removing FILE_ATTRIBUTE_READONLY");
  393. dwFileAttributes ^= FILE_ATTRIBUTE_READONLY;
  394. }
  395. return dwFileAttributes;
  396. }
  397. /*++
  398. Remove read only attribute if it's a directory
  399. --*/
  400. HANDLE
  401. APIHOOK(FindFirstFileA)(
  402. LPCSTR lpFileName,
  403. LPWIN32_FIND_DATAA lpFindFileData
  404. )
  405. {
  406. HANDLE hFindFile = ORIGINAL_API(FindFirstFileA)(lpFileName, lpFindFileData);
  407. if ((hFindFile != INVALID_HANDLE_VALUE) &&
  408. (lpFindFileData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
  409. (lpFindFileData->dwFileAttributes & FILE_ATTRIBUTE_READONLY) &&
  410. IsOnCDRom(((PFINDFILE_HANDLE) hFindFile)->DirectoryHandle))
  411. {
  412. // Flip the read-only bit
  413. LOGN(eDbgLevelWarning, "[FindFirstFileA] Removing FILE_ATTRIBUTE_READONLY");
  414. lpFindFileData->dwFileAttributes ^= FILE_ATTRIBUTE_READONLY;
  415. }
  416. return hFindFile;
  417. }
  418. /*++
  419. Remove read only attribute if it's a directory.
  420. --*/
  421. HANDLE
  422. APIHOOK(FindFirstFileW)(
  423. LPCWSTR wcsFileName,
  424. LPWIN32_FIND_DATAW lpFindFileData
  425. )
  426. {
  427. HANDLE hFindFile = ORIGINAL_API(FindFirstFileW)(wcsFileName, lpFindFileData);
  428. if ((hFindFile != INVALID_HANDLE_VALUE) &&
  429. (lpFindFileData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
  430. (lpFindFileData->dwFileAttributes & FILE_ATTRIBUTE_READONLY) &&
  431. IsOnCDRom(((PFINDFILE_HANDLE) hFindFile)->DirectoryHandle))
  432. {
  433. // It's a directory: flip the read-only bit
  434. LOGN(eDbgLevelInfo, "[FindFirstFileW] Removing FILE_ATTRIBUTE_READONLY");
  435. lpFindFileData->dwFileAttributes ^= FILE_ATTRIBUTE_READONLY;
  436. }
  437. return hFindFile;
  438. }
  439. /*++
  440. Remove read only attribute if it's a directory.
  441. --*/
  442. BOOL
  443. APIHOOK(FindNextFileA)(
  444. HANDLE hFindFile,
  445. LPWIN32_FIND_DATAA lpFindFileData
  446. )
  447. {
  448. BOOL bRet = ORIGINAL_API(FindNextFileA)(hFindFile, lpFindFileData);
  449. if (bRet &&
  450. (lpFindFileData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
  451. (lpFindFileData->dwFileAttributes & FILE_ATTRIBUTE_READONLY) &&
  452. IsOnCDRom(((PFINDFILE_HANDLE) hFindFile)->DirectoryHandle))
  453. {
  454. // Flip the read-only bit.
  455. LOGN(eDbgLevelWarning, "[FindNextFileA] Removing FILE_ATTRIBUTE_READONLY");
  456. lpFindFileData->dwFileAttributes ^= FILE_ATTRIBUTE_READONLY;
  457. }
  458. return bRet;
  459. }
  460. /*++
  461. Remove read only attribute if it's a directory.
  462. --*/
  463. BOOL
  464. APIHOOK(FindNextFileW)(
  465. HANDLE hFindFile,
  466. LPWIN32_FIND_DATAW lpFindFileData
  467. )
  468. {
  469. BOOL bRet = ORIGINAL_API(FindNextFileW)(hFindFile, lpFindFileData);
  470. if (bRet &&
  471. (lpFindFileData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
  472. (lpFindFileData->dwFileAttributes & FILE_ATTRIBUTE_READONLY) &&
  473. IsOnCDRom(((PFINDFILE_HANDLE) hFindFile)->DirectoryHandle))
  474. {
  475. // Flip the read-only bit
  476. LOGN(eDbgLevelWarning, "[FindNextFileW] Removing FILE_ATTRIBUTE_READONLY");
  477. lpFindFileData->dwFileAttributes ^= FILE_ATTRIBUTE_READONLY;
  478. }
  479. return bRet;
  480. }
  481. /*++
  482. Remove read only attribute if it's a directory.
  483. --*/
  484. BOOL
  485. APIHOOK(GetFileInformationByHandle)(
  486. HANDLE hFile,
  487. LPBY_HANDLE_FILE_INFORMATION lpFileInformation
  488. )
  489. {
  490. BOOL bRet = ORIGINAL_API(GetFileInformationByHandle)(hFile, lpFileInformation);
  491. if (bRet &&
  492. (lpFileInformation->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
  493. (lpFileInformation->dwFileAttributes & FILE_ATTRIBUTE_READONLY) &&
  494. IsOnCDRom(hFile))
  495. {
  496. // It's a CDROM: flip the read-only bit.
  497. LOGN(eDbgLevelWarning, "[GetFileInformationByHandle] Removing FILE_ATTRIBUTE_READONLY");
  498. lpFileInformation->dwFileAttributes ^= FILE_ATTRIBUTE_READONLY;
  499. }
  500. return bRet;
  501. }
  502. /*++
  503. If the disk is a CDROM, return the same wrong numbers as Win9x
  504. --*/
  505. BOOL
  506. APIHOOK(GetDiskFreeSpaceA)(
  507. LPCSTR lpRootPathName,
  508. LPDWORD lpSectorsPerCluster,
  509. LPDWORD lpBytesPerSector,
  510. LPDWORD lpNumberOfFreeClusters,
  511. LPDWORD lpTotalNumberOfClusters
  512. )
  513. {
  514. if (IsOnCDRomA(lpRootPathName))
  515. {
  516. // Hard code values to match Win9x (wrong) description of CDROM
  517. *lpSectorsPerCluster = 0x10;
  518. *lpBytesPerSector = 0x800;
  519. *lpNumberOfFreeClusters = 0;
  520. *lpTotalNumberOfClusters = 0x2b7;
  521. return TRUE;
  522. }
  523. else
  524. {
  525. // Call the original API
  526. BOOL lRet = ORIGINAL_API(GetDiskFreeSpaceA)(
  527. lpRootPathName,
  528. lpSectorsPerCluster,
  529. lpBytesPerSector,
  530. lpNumberOfFreeClusters,
  531. lpTotalNumberOfClusters);
  532. return lRet;
  533. }
  534. }
  535. /*++
  536. Initialize all the registry hooks
  537. --*/
  538. BOOL
  539. NOTIFY_FUNCTION(
  540. DWORD fdwReason
  541. )
  542. {
  543. if (fdwReason == DLL_PROCESS_ATTACH)
  544. {
  545. // Allocate our structure, if it fails, bail on the shim
  546. g_RO_Handles = new RO_FileMappingList;
  547. }
  548. return g_RO_Handles != NULL;
  549. }
  550. /*++
  551. Register hooked functions
  552. --*/
  553. HOOK_BEGIN
  554. CALL_NOTIFY_FUNCTION
  555. APIHOOK_ENTRY(KERNEL32.DLL, OpenFile)
  556. APIHOOK_ENTRY(KERNEL32.DLL, CreateFileA)
  557. APIHOOK_ENTRY(KERNEL32.DLL, CreateFileW)
  558. APIHOOK_ENTRY(KERNEL32.DLL, CreateFileMappingA)
  559. APIHOOK_ENTRY(KERNEL32.DLL, MapViewOfFile)
  560. APIHOOK_ENTRY(KERNEL32.DLL, MapViewOfFileEx)
  561. APIHOOK_ENTRY(KERNEL32.DLL, DuplicateHandle)
  562. APIHOOK_ENTRY(KERNEL32.DLL, CloseHandle)
  563. APIHOOK_ENTRY(KERNEL32.DLL, GetFileAttributesA)
  564. APIHOOK_ENTRY(KERNEL32.DLL, GetFileAttributesW)
  565. APIHOOK_ENTRY(KERNEL32.DLL, FindFirstFileA)
  566. APIHOOK_ENTRY(KERNEL32.DLL, FindFirstFileW)
  567. APIHOOK_ENTRY(KERNEL32.DLL, FindNextFileA)
  568. APIHOOK_ENTRY(KERNEL32.DLL, FindNextFileW)
  569. APIHOOK_ENTRY(KERNEL32.DLL, GetFileInformationByHandle)
  570. APIHOOK_ENTRY(KERNEL32.DLL, GetDiskFreeSpaceA)
  571. HOOK_END
  572. IMPLEMENT_SHIM_END