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.

197 lines
5.8 KiB

  1. /*
  2. * FILEMAP.C
  3. *
  4. *
  5. * DRIVEARB.DLL - Shared Drive Aribiter for shared disks and libraries
  6. * - inter-machine sharing client
  7. * - inter-app sharing service
  8. *
  9. * Author: ErvinP
  10. *
  11. * (c) 2000 Microsoft Corporation
  12. *
  13. */
  14. #include <stdlib.h>
  15. #include <wtypes.h>
  16. #include <dlmhdr.h> // BUGBUG - get a common DLM header from Cluster team
  17. #include <drivearb.h>
  18. #include "internal.h"
  19. /*
  20. * InitDrivesFileMappingForProcess
  21. *
  22. * Either create or open the drives fileMapping for this process.
  23. * Then map a process-local view to it.
  24. */
  25. BOOL InitDrivesFileMappingForProcess()
  26. {
  27. BOOL result = FALSE;
  28. /*
  29. * See if the global drives fileMapping has already
  30. * been created for some other process by trying to open it.
  31. * If not, allocate it.
  32. */
  33. g_allDrivesFileMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, DRIVES_FILEMAP_NAME);
  34. if (!g_allDrivesFileMap){
  35. g_allDrivesFileMap =
  36. CreateFileMapping(
  37. INVALID_HANDLE_VALUE, // map a portion of the paging file
  38. NULL, // BUGBUG security
  39. PAGE_READWRITE,
  40. 0,
  41. DRIVES_FILEMAP_INITIAL_SIZE*sizeof(driveContext),
  42. DRIVES_FILEMAP_NAME);
  43. }
  44. if (g_allDrivesFileMap){
  45. g_allDrivesViewPtr = MapViewOfFile(
  46. g_allDrivesFileMap,
  47. FILE_MAP_ALL_ACCESS,
  48. 0, 0, 0);
  49. if (g_allDrivesViewPtr){
  50. g_numDrivesInFileMap = DRIVES_FILEMAP_INITIAL_SIZE;
  51. result = TRUE;
  52. }
  53. else {
  54. ASSERT(g_allDrivesViewPtr);
  55. }
  56. }
  57. else {
  58. ASSERT(g_allDrivesFileMap);
  59. }
  60. return result;
  61. }
  62. /*
  63. * DestroyDrivesFileMappingForProcess
  64. *
  65. */
  66. VOID DestroyDrivesFileMappingForProcess()
  67. {
  68. if (g_allDrivesViewPtr){
  69. UnmapViewOfFile(g_allDrivesViewPtr);
  70. g_allDrivesViewPtr = NULL;
  71. }
  72. if (g_allDrivesFileMap){
  73. CloseHandle(g_allDrivesFileMap);
  74. g_allDrivesFileMap = NULL;
  75. }
  76. }
  77. /*
  78. * GrowDrivesFileMapping
  79. *
  80. * Must be called with globalMutex held.
  81. * Should only be called in the service context, not by a client.
  82. */
  83. BOOL GrowDrivesFileMapping(DWORD newNumDrives)
  84. {
  85. BOOL result = FALSE;
  86. if (newNumDrives > g_numDrivesInFileMap){
  87. HANDLE hNewFileMap;
  88. driveContext *newAllDrivesViewPtr;
  89. driveContext *drive;
  90. DWORD driveIndex;
  91. /*
  92. * Lock down every drive.
  93. * We have to do this since the common codepaths
  94. * (e.g. drive AcquireDrive/ReleaseDrive)
  95. * don't contend for the global mutex.
  96. */
  97. for (driveIndex = 0; driveIndex < g_numDrivesInFileMap; driveIndex++){
  98. drive = &g_allDrivesViewPtr[driveIndex];
  99. WaitForSingleObject(drive->mutex, INFINITE);
  100. }
  101. /*
  102. * Try to create the new, resized file map.
  103. */
  104. hNewFileMap = CreateFileMapping(
  105. INVALID_HANDLE_VALUE, // map a portion of the paging file
  106. NULL, // BUGBUG security
  107. PAGE_READWRITE,
  108. 0,
  109. newNumDrives*sizeof(driveContext),
  110. DRIVES_FILEMAP_NAME);
  111. if (hNewFileMap){
  112. newAllDrivesViewPtr = MapViewOfFile( hNewFileMap,
  113. FILE_MAP_ALL_ACCESS,
  114. 0, 0, 0);
  115. if (newAllDrivesViewPtr){
  116. RtlZeroMemory(newAllDrivesViewPtr, newNumDrives*sizeof(driveContext));
  117. /*
  118. * Copy the existing drive contexts to the new filemap.
  119. * The drive mutex and event handles remain valid as
  120. * they're copied over.
  121. */
  122. RtlCopyMemory( newAllDrivesViewPtr,
  123. g_allDrivesViewPtr,
  124. g_numDrivesInFileMap*sizeof(driveContext));
  125. /*
  126. * Mark each drive in the old fileMap as reallocated
  127. * so sessions know to refresh their handles.
  128. * (the old fileMap will stay in memory until each
  129. * session closes its old handle)
  130. */
  131. for (driveIndex = 0; driveIndex < g_numDrivesInFileMap; driveIndex++){
  132. drive = &g_allDrivesViewPtr[driveIndex];
  133. drive->isReallocated = TRUE;
  134. }
  135. result = TRUE;
  136. }
  137. else {
  138. DBGMSG("GrowDrivesFileMapping: MapViewOfFile failed", 0);
  139. CloseHandle(hNewFileMap);
  140. hNewFileMap = NULL;
  141. }
  142. }
  143. else {
  144. DBGMSG("GrowDrivesFileMapping: CreateFileMapping failed", 0);
  145. newAllDrivesViewPtr = NULL;
  146. }
  147. /*
  148. * Unlock all drives
  149. */
  150. for (driveIndex = g_numDrivesInFileMap; driveIndex > 0 ; driveIndex--){
  151. drive = &g_allDrivesViewPtr[driveIndex-1];
  152. ReleaseMutex(drive->mutex);
  153. }
  154. if (result){
  155. /*
  156. * Delete the old filemap.
  157. * The filemap will actually continue to exist until
  158. * all client session handles are removed.
  159. */
  160. UnmapViewOfFile(g_allDrivesViewPtr);
  161. CloseHandle(g_allDrivesFileMap);
  162. /*
  163. * Set globals to reflect new filemap
  164. */
  165. g_allDrivesFileMap = hNewFileMap;
  166. g_allDrivesViewPtr = newAllDrivesViewPtr;
  167. g_numDrivesInFileMap = newNumDrives;
  168. }
  169. }
  170. else {
  171. ASSERT(newNumDrives > g_numDrivesInFileMap);
  172. }
  173. return result;
  174. }