Tistory View
디스크와 볼륨은 다른 것이다. volume의 시리얼번호만으로 대부분의 상황에 대응이 가능하니 이 글에서는 Disk의 시리얼번호가 아니고 볼륨의 시리얼번호를 다룬다.
함수명은 GetVolumeInformation으로 드라이브이름, 파일시스템형태, 기본정보를 알아낼수 있습니다. VC에서 GetVolumeInformationW까지 치고 [F1]누르면 MS의 함수명세를 볼 수 있다.
GetVolumeInformation
BOOL GetVolumeInformationW(
[in, optional] LPCWSTR lpRootPathName,
[out, optional] LPWSTR lpVolumeNameBuffer,
[in] DWORD nVolumeNameSize,
[out, optional] LPDWORD lpVolumeSerialNumber,
[out, optional] LPDWORD lpMaximumComponentLength,
[out, optional] LPDWORD lpFileSystemFlags,
[out, optional] LPWSTR lpFileSystemNameBuffer,
[in] DWORD nFileSystemNameSize
);
GetVolumeInformation(W/A)중에 이젠 'A'형은 잘 안 쓸테니, 아예 'W'형의 함수 선언입니다. 헤더파일은 'fileapi.h'지만, 그냥 'windows.h'만 include하면 된다.
사용상에 주의점은..
첫번째 파라미터는 루트의 폴더 명을 넣어야 한다. 다른 말로 끝에 [\] 나 [/]를 넣어야 잘 동작을 한다. 드라이브 명만 넣을 경우 동작은 하지만, [C:]보다는 [C:\]식으로 넣는 것을 권장한다. 파티션을 볼륨이 아닌 폴더로 마운트한 경우, 해당하는 폴더명을 넣어줄때도 '\'를 넣어야 한다. 빼먹으면 실패하게 됩니다. '\'를 넣으려면 당연히 '\\'로 넣어줘야 된다. '/'로 대체가 가능한 데, window니 window식으로 넣어주는 것이 좀 더 나을 듯하다 NULL을 넣으면, 현재 디레토리의 볼륨의 정보를 받을 수 있다. 하지만, 현재 디렉토리를 체크해야 하니 그리 권장하지는 않는다.
나머지 파라미터는 대부분 정보를 받기위한 미리 준비된 공간들이다.
예제의 샘플
#include <windows.h>
#include <iostream>
//#include <fileapi.h> : enough to include windows.h
int main()
{
BOOL rcc = FALSE;
wchar_t rootPathName[] = L"C:\\";
wchar_t volumeNameBuffer[256]; // not works on subst(virtual drive)
DWORD nVolumeNameSize = sizeof( volumeNameBuffer );
DWORD volumeSerialNumber;
DWORD maximumComponentLength;
DWORD fileSystemFlags;
wchar_t fileSystemNameBuffer[32];
DWORD nFileSystemNameSize = sizeof(fileSystemNameBuffer);
setlocale(LC_ALL, "ko-KR");
rcc = GetVolumeInformationW(NULL, 0, nVolumeNameSize, &volumeSerialNumber,
&maximumComponentLength,
&fileSystemFlags,
fileSystemNameBuffer,
nFileSystemNameSize
);
if (rcc) {
wprintf(L"success : Drive=%s\n", rootPathName);
wprintf(L"volumeNameBuffer=%s\n", volumeNameBuffer );
printf("volumeSerialNumber=%08x\n", volumeSerialNumber );
printf("maximumComponentLength=%d\n", (int)maximumComponentLength);
printf("fileSystemNameBuffer=%S\n", fileSystemNameBuffer);
printf("nFileSystemNameSize=%d\n", (int)nFileSystemNameSize);
printf("fileSystemFlags=%08x\n", (int)fileSystemFlags);
printf("\tFILE_CASE_PRESERVED_NAMES=%s\n", fileSystemFlags & FILE_CASE_PRESERVED_NAMES ? "Y" : "N" );
printf("\tFILE_CASE_SENSITIVE_SEARCH=%s\n", fileSystemFlags & FILE_CASE_SENSITIVE_SEARCH ? "Y" : "N");
printf("\tFILE_DAX_VOLUME=%s\n", fileSystemFlags & FILE_DAX_VOLUME ? "Y" : "N");
printf("\tFILE_FILE_COMPRESSION=%s\n", fileSystemFlags & FILE_FILE_COMPRESSION ? "Y" : "N");
printf("\tFILE_NAMED_STREAMS=%s\n", fileSystemFlags & FILE_NAMED_STREAMS ? "Y" : "N");
printf("\tFILE_PERSISTENT_ACLS=%s\n", fileSystemFlags & FILE_PERSISTENT_ACLS ? "Y" : "N");
printf("\tFILE_READ_ONLY_VOLUME=%s\n", fileSystemFlags & FILE_READ_ONLY_VOLUME ? "Y" : "N");
printf("\tFILE_SEQUENTIAL_WRITE_ONCE=%s\n", fileSystemFlags & FILE_SEQUENTIAL_WRITE_ONCE ? "Y" : "N");
printf("\tFILE_SUPPORTS_ENCRYPTION=%s\n", fileSystemFlags & FILE_SUPPORTS_ENCRYPTION ? "Y" : "N");
printf("\tFILE_SUPPORTS_HARD_LINKS=%s\n", fileSystemFlags & FILE_SUPPORTS_HARD_LINKS ? "Y" : "N");
printf("\tFILE_SUPPORTS_OBJECT_IDS=%s\n", fileSystemFlags & FILE_SUPPORTS_OBJECT_IDS ? "Y" : "N");
printf("\tFILE_SUPPORTS_REPARSE_POINTS=%s\n", fileSystemFlags & FILE_SUPPORTS_REPARSE_POINTS ? "Y" : "N");
printf("\tFILE_SUPPORTS_SPARSE_FILES=%s\n", fileSystemFlags & FILE_SUPPORTS_SPARSE_FILES ? "Y" : "N");
printf("\tFILE_SUPPORTS_TRANSACTIONS=%s\n", fileSystemFlags & FILE_SUPPORTS_TRANSACTIONS ? "Y" : "N");
printf("\tFILE_SUPPORTS_USN_JOURNAL=%s\n", fileSystemFlags & FILE_SUPPORTS_USN_JOURNAL ? "Y" : "N");
printf("\tFILE_UNICODE_ON_DISK=%s\n", fileSystemFlags & FILE_UNICODE_ON_DISK ? "Y" : "N");
printf("\tFILE_VOLUME_IS_COMPRESSED=%s\n", fileSystemFlags & FILE_VOLUME_IS_COMPRESSED ? "Y" : "N");
printf("\tFILE_VOLUME_QUOTAS=%s\n", fileSystemFlags & FILE_VOLUME_QUOTAS ? "Y" : "N");
printf("\tFILE_SUPPORTS_BLOCK_REFCOUNTING=%s\n", fileSystemFlags & FILE_SUPPORTS_BLOCK_REFCOUNTING ? "Y" : "N");
}
else {
printf("Can't GetVolumeInformationW\n");
}
return 0;
}
rootPathName 변수만 변경해가며 사용할 수 있게 만들었다..
네트워크드라이브는?
네트워크 드라이브의 경우 NTFS로 필자는 잡혔다. 실제로 SPARSED같은 것을 지원하는 지의 의문이다. 이 부분은 테스트 후 내용을 업데이트할 예정이다.
나오는 정보중에 maximumComponentLength값은... 필자는 못 믿겠다.
시리얼번호
단순한 32bits의 코드일 뿐이고, 명령창의 dir명령에서 확인할 수 있다.
이 시리얼번호는 포맷할 때마다 변하게 된다. 그리고 32bits라는 한계로인해 "겹치지 않는다"고 확정은 할 수 없고, 겹칠 확률이 아주 적기는 하지만 UUID같이 아주 희박한 것은 아니다. 문제는 디스크복사기와 같은 것을 사용할 경우 동일한 시리얼번호를 가질 수 있으니, 이 시리얼번호를 이용한 처리는 신중할 필요가 있다.
ext4같은 파티션도 시리얼 번호를 읽을 수 있는가? 아니오, 마운트된 드라이브만 가능하기에 루트폴더를 지정할 수 없다면 시리얼번호를 읽을 수 없다. EXT4와 같은 것을 마운트해주는 프로그램을 테스트해보지는 않았다.(있긴 있는지..)
보통의 NTFS정보
일반적으로 NTFS포맷을 사용한 드라이브의 정보는 다음과 같다. 물론 DAX같은 경우는 변경이 가능하기 때문에, 다른 값을 가질 수 있지만, 일반적으로 다음과 같다.
레퍼런스
'MS Windows' 카테고리의 다른 글
VC 디스크 드라이브 목록 구하기 (1) | 2022.08.02 |
---|---|
LDPlayer 개발자모드 (1) | 2022.07.29 |
윈도우 폴더를 드라이브로 subst (1) | 2022.07.25 |
윈도우 드라이브 볼륨을 폴더로 링크 mklink (0) | 2022.07.24 |
LDPlayer 빠른 안드로이드 에뮬레이터 9버전 출시 (0) | 2022.07.21 |
- Total
- Today
- Yesterday
- OpenGLes
- OpenGL ES
- 금리
- 공유 컨텍스트
- 전기료
- gpgpu
- 안드로이드
- 티스토리
- TTS
- 애드핏
- 전기요금
- Android
- 에어콘
- 사용료
- choreographer
- 텍스처
- 재태크
- 에어컨
- 전기세
- 경제보복
- 블로그
- 예금
- 재테크
- texture
- 컴퓨트쉐이더
- 컴퓨트셰이더
- 적금
- ComputeShader
- 아끼는 법
- 애드센스
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |