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.

158 lines
3.8 KiB

  1. /*
  2. * DRIVE.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. * NewDriveContext
  21. *
  22. * Must be called with globalMutex held.
  23. * Should only be called in the service context, not by a client.
  24. *
  25. */
  26. driveContext *NewDriveContext(LPSTR driveName)
  27. {
  28. driveContext *drive = NULL;
  29. DWORD driveIndex;
  30. /*
  31. * Find an available drive context
  32. *
  33. * BUGBUG - make this more efficient; e.g. use a free list
  34. */
  35. for (driveIndex = 0; driveIndex < g_numDrivesInFileMap; driveIndex++){
  36. driveContext *d = &g_allDrivesViewPtr[driveIndex];
  37. if (d->state == DRIVESTATE_NONE){
  38. drive = d;
  39. break;
  40. }
  41. }
  42. if (drive){
  43. char driveMutexName[sizeof(DRIVE_MUTEX_NAME_PREFIX)+8];
  44. drive->sig = DRIVEARB_SIG;
  45. wsprintf(driveMutexName, "%s%08x", DRIVE_MUTEX_NAME_PREFIX, driveIndex);
  46. drive->mutex = CreateMutex(NULL, FALSE, (LPSTR)driveMutexName);
  47. if (drive->mutex){
  48. char driveEventName[sizeof(DRIVE_EVENT_NAME_PREFIX)+8];
  49. wsprintf(driveEventName, "%s%08x", DRIVE_EVENT_NAME_PREFIX, driveIndex);
  50. drive->event = CreateEvent(NULL, FALSE, FALSE, (LPSTR)driveEventName);
  51. if (drive->event){
  52. drive->state = DRIVESTATE_UNAVAILABLE_LOCALLY;
  53. MyStrNCpy(drive->driveName, driveName, MAX_PATH);
  54. // DBGMSG("NewDriveContext created drive:", driveIndex);
  55. // DBGMSG(drive->driveName, 0);
  56. }
  57. else {
  58. CloseHandle(drive->mutex);
  59. drive = NULL;
  60. }
  61. }
  62. else {
  63. drive = NULL;
  64. }
  65. }
  66. else {
  67. /*
  68. * No more free drive contexts in the current fileMap.
  69. * So grow the fileMap and try again.
  70. */
  71. BOOL ok = GrowDrivesFileMapping(g_numDrivesInFileMap*2);
  72. if (ok){
  73. drive = NewDriveContext(driveName);
  74. }
  75. }
  76. return drive;
  77. }
  78. /*
  79. * FreeDriveContext
  80. *
  81. * Must be called with globalMutex held.
  82. * Should only be called in the service context, not by a client.
  83. *
  84. */
  85. VOID FreeDriveContext(driveContext *drive)
  86. {
  87. CloseHandle(drive->mutex);
  88. CloseHandle(drive->event);
  89. drive->state = DRIVESTATE_NONE;
  90. }
  91. /*
  92. * GetDriveIndexByName
  93. *
  94. * Must be called with globalMutex held.
  95. *
  96. * Return drive index if it exists; else return -1.
  97. */
  98. DWORD GetDriveIndexByName(LPSTR driveName)
  99. {
  100. HANDLE hDrivesFileMap;
  101. DWORD driveIndex = -1;
  102. /*
  103. * Create a temporary read-only mapping of the entire drives array
  104. * so we can look for the drive.
  105. */
  106. hDrivesFileMap = OpenFileMapping(FILE_MAP_READ, FALSE, DRIVES_FILEMAP_NAME);
  107. if (hDrivesFileMap){
  108. driveContext *allDrivesViewPtr = MapViewOfFile(hDrivesFileMap, FILE_MAP_READ, 0, 0, 0);
  109. if (allDrivesViewPtr){
  110. DWORD i;
  111. for (i = 0; i < g_numDrivesInFileMap; i++){
  112. driveContext *d = &allDrivesViewPtr[i];
  113. if ((d->state != DRIVESTATE_NONE) &&
  114. MyCompareStringsI(d->driveName, driveName)){
  115. driveIndex = i;
  116. break;
  117. }
  118. }
  119. UnmapViewOfFile(allDrivesViewPtr);
  120. }
  121. else {
  122. ASSERT(allDrivesViewPtr);
  123. }
  124. CloseHandle(hDrivesFileMap);
  125. }
  126. else {
  127. ASSERT(hDrivesFileMap);
  128. }
  129. ASSERT(driveIndex != -1);
  130. return driveIndex;
  131. }