/* * SESSION.C * * * DRIVEARB.DLL - Shared Drive Aribiter for shared disks and libraries * - inter-machine sharing client * - inter-app sharing service * * Author: ErvinP * * (c) 2000 Microsoft Corporation * */ #include #include #include // BUGBUG - get a common DLM header from Cluster team #include #include "internal.h" clientSessionContext *NewClientSession(LPSTR driveName) { clientSessionContext *session; session = (clientSessionContext *)GlobalAlloc( GMEM_FIXED|GMEM_ZEROINIT, sizeof(clientSessionContext)); if (session){ BOOL success = FALSE; session->sig = DRIVEARB_SIG; WaitForSingleObject(g_hSharedGlobalMutex, INFINITE); session->driveIndex = GetDriveIndexByName(driveName); if (session->driveIndex != -1){ /* * Map just this one drive context into this process' address space. */ session->hDrivesFileMap = OpenFileMapping( FILE_MAP_ALL_ACCESS, FALSE, DRIVES_FILEMAP_NAME); if (session->hDrivesFileMap){ session->driveViewPtr = MapViewOfFile( session->hDrivesFileMap, FILE_MAP_ALL_ACCESS, 0, session->driveIndex*sizeof(driveContext), sizeof(driveContext)); if (session->driveViewPtr){ /* * Map the drive mutex into this process' address space */ char driveMutexName[sizeof(DRIVE_MUTEX_NAME_PREFIX)+8]; wsprintf(driveMutexName, "%s%08x", DRIVE_MUTEX_NAME_PREFIX, session->driveIndex); session->sessionDriveMutex = OpenMutex(SYNCHRONIZE, FALSE, (LPSTR)driveMutexName); if (session->sessionDriveMutex){ /* * Map the drive event into this process' address space */ char driveEventName[sizeof(DRIVE_EVENT_NAME_PREFIX)+8]; wsprintf(driveEventName, "%s%08x", DRIVE_EVENT_NAME_PREFIX, session->driveIndex); session->sessionDriveEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, (LPSTR)driveEventName); if (session->sessionDriveEvent){ session->state = CLIENTSTATE_INACTIVE; success = TRUE; } else { ASSERT(session->sessionDriveEvent); } } else { ASSERT(session->sessionDriveMutex); } } else { ASSERT(session->driveViewPtr); } } else { ASSERT(session->hDrivesFileMap); } } else { ASSERT(session->driveIndex != -1); } ReleaseMutex(g_hSharedGlobalMutex); if (!success){ FreeClientSession(session); session = NULL; } } else { ASSERT(session); } ASSERT(session); return session; } VOID FreeClientSession(clientSessionContext *session) { /* * This function is also called for error cases in NewClientSession, * so check each object before freeing it. */ if (session->driveViewPtr){ UnmapViewOfFile(session->driveViewPtr); } if (session->hDrivesFileMap){ CloseHandle(session->hDrivesFileMap); } if (session->sessionDriveMutex){ CloseHandle(session->sessionDriveMutex); } if (session->sessionDriveEvent){ CloseHandle(session->sessionDriveEvent); } GlobalFree(session); } BOOL LOCKDriveForSession(clientSessionContext *session) { BOOL result; WaitForSingleObject(session->sessionDriveMutex, INFINITE); if (session->driveViewPtr->isReallocated){ /* * The drive filemap was reallocated. * Refresh this sessions's filemap. */ UnmapViewOfFile(session->driveViewPtr); CloseHandle(session->hDrivesFileMap); session->hDrivesFileMap = OpenFileMapping( FILE_MAP_ALL_ACCESS, FALSE, DRIVES_FILEMAP_NAME); if (session->hDrivesFileMap){ session->driveViewPtr = MapViewOfFile( session->hDrivesFileMap, FILE_MAP_READ, 0, session->driveIndex*sizeof(driveContext), sizeof(driveContext)); if (session->driveViewPtr){ /* * No need to set isReallocated = FALSE * since driveViewPtr is now pointing to a fresh context. */ result = TRUE; } else { ASSERT(session->driveViewPtr); CloseHandle(session->hDrivesFileMap); session->hDrivesFileMap = NULL; result = FALSE; } } else { ASSERT(session->hDrivesFileMap); session->driveViewPtr = NULL; result = FALSE; } if (!result){ ReleaseMutex(session->sessionDriveMutex); /* * Call the client's invalidateHandleProc callback to let them * know that the session is now invalid. * Must call this with sessionDriveMutex released because * the client will call CloseDriveSession inside this call. * There is no race condition wrt not holding the mutex * because we're still inside a client's call on this session * (client must synchronize calls on a session). */ ASSERT(session->invalidateHandleProc); session->invalidateHandleProc(session); } } else { result = TRUE; } return result; } VOID UNLOCKDriveForSession(clientSessionContext *session) { ReleaseMutex(session->sessionDriveMutex); }