void DriveMng::SetDriveMap(char *_driveMap) { if (strcmp(_driveMap, driveMap) == 0) return; DWORD val = 1; Init(); strcpy(driveMap, _driveMap); for (char *c=driveMap; *c; c++) { if (*c == ',') val++; else RegisterDriveID(LetterToIndex(*c), &val, sizeof(val)); } }
BOOL DriveMng::SetDriveID(int drvLetter) { TRegistry reg(HKEY_LOCAL_MACHINE); BYTE buf[1024]; WCHAR *wbuf = (WCHAR *)buf; char reg_path[MAX_PATH * 2]; int size, idx = LetterToIndex(drvLetter); DWORD val = 0; // NT 系 if (IS_WINNT_V) { if (reg.OpenKey(MOUNTED_DEVICES)) { ::sprintf(reg_path, FMT_DOSDEVICES, drvLetter); size = sizeof(buf); if (reg.GetByte(reg_path, buf, &size)) { if (wcsncmp(wbuf, L"\\??\\", 4) == 0 && (wbuf = wcschr(wbuf, '#')) && (wbuf = wcschr(wbuf+1, '#')) && (wbuf = wcschr(wbuf, '&'))) { val = wcstoul(wbuf+1, 0, 16); } else { val = *(DWORD *)buf; } if (val <= 30) val |= 0x88000000; return RegisterDriveID(idx, &val, sizeof(val)); } } return RegisterDriveID(idx, &val, 1); } // 95 系 TRegistry dynReg(HKEY_DYN_DATA); char dyn_path[MAX_PATH]; int no_id_cnt = 0; if (reg.OpenKey(ENUM_DEVICES)) { for (int i=0; reg.EnumKey(i, reg_path, MAX_PATH); i++) { // SCSI, etc... if (reg.OpenKey(reg_path) == FALSE) continue; char *ctrl = reg_path + strlen(reg_path); *ctrl++ = '\\'; for (int j=0; reg.EnumKey(j, ctrl, MAX_PATH); j++) { // Controller if (reg.OpenKey(ctrl) == FALSE) continue; char *dev = ctrl + strlen(ctrl); *dev++ = '\\'; for (int k=0; reg.EnumKey(k, dev, MAX_PATH); k++) { // Devices... if (reg.OpenKey(dev) == FALSE) continue; val = 0; if (reg.GetStr(DRIVE_LETTERS, (char *)buf, sizeof(buf))) { if (*buf == 0) no_id_cnt++; // format 後、reboot するまで registry に未反映らしい for (int l=0; buf[l]; l++) { if (drvLetter == buf[l]) { val = 1; break; } } } if (val && dynReg.OpenKey(CONFIG_ENUM)) { for (int m=0; dynReg.EnumKey(m, dyn_path, sizeof(dyn_path)); m++) { if (dynReg.OpenKey(dyn_path) == FALSE) continue; if (dynReg.GetStr(HARDWARE_KEY, (char *)buf, sizeof(buf))) { if (strcmp(reg_path, (char *)buf) == 0) { return RegisterDriveID(idx, buf, (int)strlen((char *)buf)); } } dynReg.CloseKey(); } dynReg.CloseKey(); } reg.CloseKey(); } reg.CloseKey(); } reg.CloseKey(); } } if (noIdCnt == 0) noIdCnt = no_id_cnt; val = 0; return RegisterDriveID(idx, &val, sizeof(val)); }
int DriveMng::SetDriveID(const WCHAR *_root) { if (!_root || !_root[0]) return -1; WCHAR root[MAX_PATH]; int idx = -1; ::CharUpperW(wcscpy(root, _root)); if (root[1] == ':') { idx = DrvLetterToIndex(root[0]); if (idx < 0 || idx >= MAX_LOCAL_DRIVES) return -1; } else { // ネットワークドライブの場合、\\server\volume\ もしくは \\server\ (設定に依存) // を大文字にした文字列のハッシュ値を識別値(drvId[].data)とする ModifyNetRoot(root); uint64 hash_id = MakeHash64(root, (int)wcslen(root)); if ((idx = shareInfo->RegisterNetDrive(hash_id)) < 0) return -1; if (drvID[idx].len) return idx; // already registerd RegisterDriveID(idx, &hash_id, sizeof(hash_id)); return idx; } if (drvID[idx].len) return idx; // already registerd if (::GetDriveTypeW(root) == DRIVE_REMOTE) { BYTE buf[2048]; DWORD size = sizeof(buf); REMOTE_NAME_INFOW *pni = (REMOTE_NAME_INFOW *)buf; if (::WNetGetUniversalNameW(root, REMOTE_NAME_INFO_LEVEL, pni, &size) != NO_ERROR) { //Debug("WNetGetUniversalNameW err=%d\n", GetLastError()); return -1; } wcscpy(root, pni->lpUniversalName); ::CharUpperW(root); ModifyNetRoot(root); uint64 hash_id = MakeHash64(root, (int)wcslen(root)); RegisterDriveID(idx, &hash_id, sizeof(hash_id)); int net_idx = shareInfo->RegisterNetDrive(hash_id); if (net_idx >= 0) RegisterDriveID(net_idx, &hash_id, sizeof(hash_id)); return idx; } WCHAR vol_name[MAX_PATH]; if (::GetVolumeNameForVolumeMountPointW(root, vol_name, MAX_PATH)) { vol_name[wcslen(vol_name) -1] = 0; HANDLE hFile = ::CreateFileW(vol_name, FILE_READ_ATTRIBUTES, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); if (hFile != INVALID_HANDLE_VALUE) { VOLUME_DISK_EXTENTS vde = {}; DWORD size; DWORD val = 0; if (::DeviceIoControl(hFile, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, 0, 0, &vde, sizeof(vde), &size, 0) || GetLastError() == ERROR_MORE_DATA) { if (vde.NumberOfDiskExtents >= 1) { // SetDriveMapが ID: 1~Nを利用するため、オフセット0x1000を加算 val = vde.Extents[0].DiskNumber | 0x1000; //Debug("disk id = %d\n", vde.Extents[0].DiskNumber); } } ::CloseHandle(hFile); if (val) { RegisterDriveID(idx, &val, sizeof(val)); return idx; } } } TRegistry reg(HKEY_LOCAL_MACHINE); if (reg.OpenKey(MOUNTED_DEVICES)) { char reg_path[MAX_PATH * 2]; BYTE buf[1024]; int size = sizeof(buf); WCHAR *wbuf = (WCHAR *)buf, *wp; DWORD val = 0; ::sprintf(reg_path, FMT_DOSDEVICES, root[0]); if (reg.GetByte(reg_path, buf, &size)) { if (wcsncmp(wbuf, L"\\??\\", 4) == 0 && (wp = wcschr(wbuf, '#')) && (wp = wcschr(wp+1, '#')) && (wp = wcschr(wp, '&'))) { val = wcstoul(wp+1, 0, 16); } else if (wcsncmp(wbuf, L"_??_", 4) == 0 && (wp = wcschr(wbuf, '{'))) { val = wcstoul(wp+1, 0, 16); } else if (wcsncmp(wbuf, L"DMIO:ID:", 8) == 0) { val = *(DWORD *)(wbuf + 8); } else { val = *(DWORD *)buf; } if (val <= 30) val |= 0x88000000; RegisterDriveID(idx, &val, sizeof(val)); return idx; } } RegisterDriveID(idx, "", 1); return idx; }