/* * DRIVE.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" /* * NewDriveContext * * Must be called with globalMutex held. * Should only be called in the service context, not by a client. * */ driveContext *NewDriveContext(LPSTR driveName) { driveContext *drive = NULL; DWORD driveIndex; /* * Find an available drive context * * BUGBUG - make this more efficient; e.g. use a free list */ for (driveIndex = 0; driveIndex < g_numDrivesInFileMap; driveIndex++){ driveContext *d = &g_allDrivesViewPtr[driveIndex]; if (d->state == DRIVESTATE_NONE){ drive = d; break; } } if (drive){ char driveMutexName[sizeof(DRIVE_MUTEX_NAME_PREFIX)+8]; drive->sig = DRIVEARB_SIG; wsprintf(driveMutexName, "%s%08x", DRIVE_MUTEX_NAME_PREFIX, driveIndex); drive->mutex = CreateMutex(NULL, FALSE, (LPSTR)driveMutexName); if (drive->mutex){ char driveEventName[sizeof(DRIVE_EVENT_NAME_PREFIX)+8]; wsprintf(driveEventName, "%s%08x", DRIVE_EVENT_NAME_PREFIX, driveIndex); drive->event = CreateEvent(NULL, FALSE, FALSE, (LPSTR)driveEventName); if (drive->event){ drive->state = DRIVESTATE_UNAVAILABLE_LOCALLY; MyStrNCpy(drive->driveName, driveName, MAX_PATH); // DBGMSG("NewDriveContext created drive:", driveIndex); // DBGMSG(drive->driveName, 0); } else { CloseHandle(drive->mutex); drive = NULL; } } else { drive = NULL; } } else { /* * No more free drive contexts in the current fileMap. * So grow the fileMap and try again. */ BOOL ok = GrowDrivesFileMapping(g_numDrivesInFileMap*2); if (ok){ drive = NewDriveContext(driveName); } } return drive; } /* * FreeDriveContext * * Must be called with globalMutex held. * Should only be called in the service context, not by a client. * */ VOID FreeDriveContext(driveContext *drive) { CloseHandle(drive->mutex); CloseHandle(drive->event); drive->state = DRIVESTATE_NONE; } /* * GetDriveIndexByName * * Must be called with globalMutex held. * * Return drive index if it exists; else return -1. */ DWORD GetDriveIndexByName(LPSTR driveName) { HANDLE hDrivesFileMap; DWORD driveIndex = -1; /* * Create a temporary read-only mapping of the entire drives array * so we can look for the drive. */ hDrivesFileMap = OpenFileMapping(FILE_MAP_READ, FALSE, DRIVES_FILEMAP_NAME); if (hDrivesFileMap){ driveContext *allDrivesViewPtr = MapViewOfFile(hDrivesFileMap, FILE_MAP_READ, 0, 0, 0); if (allDrivesViewPtr){ DWORD i; for (i = 0; i < g_numDrivesInFileMap; i++){ driveContext *d = &allDrivesViewPtr[i]; if ((d->state != DRIVESTATE_NONE) && MyCompareStringsI(d->driveName, driveName)){ driveIndex = i; break; } } UnmapViewOfFile(allDrivesViewPtr); } else { ASSERT(allDrivesViewPtr); } CloseHandle(hDrivesFileMap); } else { ASSERT(hDrivesFileMap); } ASSERT(driveIndex != -1); return driveIndex; }