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.

213 lines
6.6 KiB

  1. /*
  2. * SESSION.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. clientSessionContext *NewClientSession(LPSTR driveName)
  20. {
  21. clientSessionContext *session;
  22. session = (clientSessionContext *)GlobalAlloc(
  23. GMEM_FIXED|GMEM_ZEROINIT,
  24. sizeof(clientSessionContext));
  25. if (session){
  26. BOOL success = FALSE;
  27. session->sig = DRIVEARB_SIG;
  28. WaitForSingleObject(g_hSharedGlobalMutex, INFINITE);
  29. session->driveIndex = GetDriveIndexByName(driveName);
  30. if (session->driveIndex != -1){
  31. /*
  32. * Map just this one drive context into this process' address space.
  33. */
  34. session->hDrivesFileMap = OpenFileMapping(
  35. FILE_MAP_ALL_ACCESS,
  36. FALSE,
  37. DRIVES_FILEMAP_NAME);
  38. if (session->hDrivesFileMap){
  39. session->driveViewPtr = MapViewOfFile(
  40. session->hDrivesFileMap,
  41. FILE_MAP_ALL_ACCESS,
  42. 0,
  43. session->driveIndex*sizeof(driveContext),
  44. sizeof(driveContext));
  45. if (session->driveViewPtr){
  46. /*
  47. * Map the drive mutex into this process' address space
  48. */
  49. char driveMutexName[sizeof(DRIVE_MUTEX_NAME_PREFIX)+8];
  50. wsprintf(driveMutexName, "%s%08x", DRIVE_MUTEX_NAME_PREFIX, session->driveIndex);
  51. session->sessionDriveMutex = OpenMutex(SYNCHRONIZE, FALSE, (LPSTR)driveMutexName);
  52. if (session->sessionDriveMutex){
  53. /*
  54. * Map the drive event into this process' address space
  55. */
  56. char driveEventName[sizeof(DRIVE_EVENT_NAME_PREFIX)+8];
  57. wsprintf(driveEventName, "%s%08x", DRIVE_EVENT_NAME_PREFIX, session->driveIndex);
  58. session->sessionDriveEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, (LPSTR)driveEventName);
  59. if (session->sessionDriveEvent){
  60. session->state = CLIENTSTATE_INACTIVE;
  61. success = TRUE;
  62. }
  63. else {
  64. ASSERT(session->sessionDriveEvent);
  65. }
  66. }
  67. else {
  68. ASSERT(session->sessionDriveMutex);
  69. }
  70. }
  71. else {
  72. ASSERT(session->driveViewPtr);
  73. }
  74. }
  75. else {
  76. ASSERT(session->hDrivesFileMap);
  77. }
  78. }
  79. else {
  80. ASSERT(session->driveIndex != -1);
  81. }
  82. ReleaseMutex(g_hSharedGlobalMutex);
  83. if (!success){
  84. FreeClientSession(session);
  85. session = NULL;
  86. }
  87. }
  88. else {
  89. ASSERT(session);
  90. }
  91. ASSERT(session);
  92. return session;
  93. }
  94. VOID FreeClientSession(clientSessionContext *session)
  95. {
  96. /*
  97. * This function is also called for error cases in NewClientSession,
  98. * so check each object before freeing it.
  99. */
  100. if (session->driveViewPtr){
  101. UnmapViewOfFile(session->driveViewPtr);
  102. }
  103. if (session->hDrivesFileMap){
  104. CloseHandle(session->hDrivesFileMap);
  105. }
  106. if (session->sessionDriveMutex){
  107. CloseHandle(session->sessionDriveMutex);
  108. }
  109. if (session->sessionDriveEvent){
  110. CloseHandle(session->sessionDriveEvent);
  111. }
  112. GlobalFree(session);
  113. }
  114. BOOL LOCKDriveForSession(clientSessionContext *session)
  115. {
  116. BOOL result;
  117. WaitForSingleObject(session->sessionDriveMutex, INFINITE);
  118. if (session->driveViewPtr->isReallocated){
  119. /*
  120. * The drive filemap was reallocated.
  121. * Refresh this sessions's filemap.
  122. */
  123. UnmapViewOfFile(session->driveViewPtr);
  124. CloseHandle(session->hDrivesFileMap);
  125. session->hDrivesFileMap = OpenFileMapping(
  126. FILE_MAP_ALL_ACCESS,
  127. FALSE,
  128. DRIVES_FILEMAP_NAME);
  129. if (session->hDrivesFileMap){
  130. session->driveViewPtr = MapViewOfFile(
  131. session->hDrivesFileMap,
  132. FILE_MAP_READ,
  133. 0,
  134. session->driveIndex*sizeof(driveContext),
  135. sizeof(driveContext));
  136. if (session->driveViewPtr){
  137. /*
  138. * No need to set isReallocated = FALSE
  139. * since driveViewPtr is now pointing to a fresh context.
  140. */
  141. result = TRUE;
  142. }
  143. else {
  144. ASSERT(session->driveViewPtr);
  145. CloseHandle(session->hDrivesFileMap);
  146. session->hDrivesFileMap = NULL;
  147. result = FALSE;
  148. }
  149. }
  150. else {
  151. ASSERT(session->hDrivesFileMap);
  152. session->driveViewPtr = NULL;
  153. result = FALSE;
  154. }
  155. if (!result){
  156. ReleaseMutex(session->sessionDriveMutex);
  157. /*
  158. * Call the client's invalidateHandleProc callback to let them
  159. * know that the session is now invalid.
  160. * Must call this with sessionDriveMutex released because
  161. * the client will call CloseDriveSession inside this call.
  162. * There is no race condition wrt not holding the mutex
  163. * because we're still inside a client's call on this session
  164. * (client must synchronize calls on a session).
  165. */
  166. ASSERT(session->invalidateHandleProc);
  167. session->invalidateHandleProc(session);
  168. }
  169. }
  170. else {
  171. result = TRUE;
  172. }
  173. return result;
  174. }
  175. VOID UNLOCKDriveForSession(clientSessionContext *session)
  176. {
  177. ReleaseMutex(session->sessionDriveMutex);
  178. }