/* * FILEMAP.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" /* * InitDrivesFileMappingForProcess * * Either create or open the drives fileMapping for this process. * Then map a process-local view to it. */ BOOL InitDrivesFileMappingForProcess() { BOOL result = FALSE; /* * See if the global drives fileMapping has already * been created for some other process by trying to open it. * If not, allocate it. */ g_allDrivesFileMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, DRIVES_FILEMAP_NAME); if (!g_allDrivesFileMap){ g_allDrivesFileMap = CreateFileMapping( INVALID_HANDLE_VALUE, // map a portion of the paging file NULL, // BUGBUG security PAGE_READWRITE, 0, DRIVES_FILEMAP_INITIAL_SIZE*sizeof(driveContext), DRIVES_FILEMAP_NAME); } if (g_allDrivesFileMap){ g_allDrivesViewPtr = MapViewOfFile( g_allDrivesFileMap, FILE_MAP_ALL_ACCESS, 0, 0, 0); if (g_allDrivesViewPtr){ g_numDrivesInFileMap = DRIVES_FILEMAP_INITIAL_SIZE; result = TRUE; } else { ASSERT(g_allDrivesViewPtr); } } else { ASSERT(g_allDrivesFileMap); } return result; } /* * DestroyDrivesFileMappingForProcess * */ VOID DestroyDrivesFileMappingForProcess() { if (g_allDrivesViewPtr){ UnmapViewOfFile(g_allDrivesViewPtr); g_allDrivesViewPtr = NULL; } if (g_allDrivesFileMap){ CloseHandle(g_allDrivesFileMap); g_allDrivesFileMap = NULL; } } /* * GrowDrivesFileMapping * * Must be called with globalMutex held. * Should only be called in the service context, not by a client. */ BOOL GrowDrivesFileMapping(DWORD newNumDrives) { BOOL result = FALSE; if (newNumDrives > g_numDrivesInFileMap){ HANDLE hNewFileMap; driveContext *newAllDrivesViewPtr; driveContext *drive; DWORD driveIndex; /* * Lock down every drive. * We have to do this since the common codepaths * (e.g. drive AcquireDrive/ReleaseDrive) * don't contend for the global mutex. */ for (driveIndex = 0; driveIndex < g_numDrivesInFileMap; driveIndex++){ drive = &g_allDrivesViewPtr[driveIndex]; WaitForSingleObject(drive->mutex, INFINITE); } /* * Try to create the new, resized file map. */ hNewFileMap = CreateFileMapping( INVALID_HANDLE_VALUE, // map a portion of the paging file NULL, // BUGBUG security PAGE_READWRITE, 0, newNumDrives*sizeof(driveContext), DRIVES_FILEMAP_NAME); if (hNewFileMap){ newAllDrivesViewPtr = MapViewOfFile( hNewFileMap, FILE_MAP_ALL_ACCESS, 0, 0, 0); if (newAllDrivesViewPtr){ RtlZeroMemory(newAllDrivesViewPtr, newNumDrives*sizeof(driveContext)); /* * Copy the existing drive contexts to the new filemap. * The drive mutex and event handles remain valid as * they're copied over. */ RtlCopyMemory( newAllDrivesViewPtr, g_allDrivesViewPtr, g_numDrivesInFileMap*sizeof(driveContext)); /* * Mark each drive in the old fileMap as reallocated * so sessions know to refresh their handles. * (the old fileMap will stay in memory until each * session closes its old handle) */ for (driveIndex = 0; driveIndex < g_numDrivesInFileMap; driveIndex++){ drive = &g_allDrivesViewPtr[driveIndex]; drive->isReallocated = TRUE; } result = TRUE; } else { DBGMSG("GrowDrivesFileMapping: MapViewOfFile failed", 0); CloseHandle(hNewFileMap); hNewFileMap = NULL; } } else { DBGMSG("GrowDrivesFileMapping: CreateFileMapping failed", 0); newAllDrivesViewPtr = NULL; } /* * Unlock all drives */ for (driveIndex = g_numDrivesInFileMap; driveIndex > 0 ; driveIndex--){ drive = &g_allDrivesViewPtr[driveIndex-1]; ReleaseMutex(drive->mutex); } if (result){ /* * Delete the old filemap. * The filemap will actually continue to exist until * all client session handles are removed. */ UnmapViewOfFile(g_allDrivesViewPtr); CloseHandle(g_allDrivesFileMap); /* * Set globals to reflect new filemap */ g_allDrivesFileMap = hNewFileMap; g_allDrivesViewPtr = newAllDrivesViewPtr; g_numDrivesInFileMap = newNumDrives; } } else { ASSERT(newNumDrives > g_numDrivesInFileMap); } return result; }