Example #1
0
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));
	}
}
Example #2
0
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));
}
Example #3
0
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;
}