Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

428 lines
14 KiB

  1. #include <tchar.h>
  2. #include <stdio.h>
  3. #include <windows.h>
  4. #include <winnetp.h>
  5. #define PRINTCASE(a) case (a): _tprintf(TEXT("%s"), TEXT(#a)); break;
  6. #define FLAG_HELP 0x00000001
  7. #define FLAG_DEBUG 0x00000002
  8. #define FLAG_DRIVE 0x00000004
  9. #define FLAG_FILE 0x00000008
  10. #define FLAG_NETWORK 0x00000010
  11. #define FLAG_LOGDRIVE 0x00000020
  12. #define FLAG_MOUNTPOINT 0x00000040
  13. #define FLAG_VOLUMEGUID 0x00000080
  14. #define ARRAYSIZE(a) (sizeof((a))/sizeof((a)[0]))
  15. typedef struct _tagFLAGASSOC
  16. {
  17. TCHAR szName;
  18. DWORD dwFlag;
  19. } FLAGASSOC;
  20. FLAGASSOC FlagList[] =
  21. {
  22. { TEXT('?'), FLAG_HELP },
  23. { TEXT('b'), FLAG_DEBUG },
  24. { TEXT('d'), FLAG_DRIVE },
  25. { TEXT('f'), FLAG_FILE },
  26. { TEXT('n'), FLAG_NETWORK },
  27. { TEXT('l'), FLAG_LOGDRIVE },
  28. #if 0
  29. { TEXT('m'), FLAG_MOUNTPOINT },
  30. { TEXT('g'), FLAG_VOLUMEGUID },
  31. #endif
  32. };
  33. #ifdef UNICODE
  34. extern "C"
  35. {
  36. int __cdecl wmain(int argc, wchar_t* argv[])
  37. #else
  38. int __cdecl main(int argc, char* argv[])
  39. #endif
  40. {
  41. TCHAR szName[MAX_PATH];
  42. DWORD dwFlags = 0;
  43. BOOL fGotFileName = FALSE;
  44. // process the args
  45. for (int i = 1; i < argc; ++i)
  46. {
  47. if ((TEXT('/') == argv[i][0]) || (TEXT('-') == argv[i][0]))
  48. {
  49. // This is a flag
  50. for (int j = 0; j < ARRAYSIZE(FlagList); ++j)
  51. {
  52. if ((FlagList[j].szName == argv[i][1]) ||
  53. ((FlagList[j].szName + (TEXT('a') - TEXT('A'))) == argv[i][1]))
  54. {
  55. dwFlags |= FlagList[j].dwFlag;
  56. break;
  57. }
  58. }
  59. }
  60. else
  61. {
  62. // This is the filename
  63. lstrcpyn(szName, argv[i], ARRAYSIZE(szName));
  64. fGotFileName = TRUE;
  65. }
  66. }
  67. if (!fGotFileName)
  68. {
  69. if (!GetCurrentDirectory(ARRAYSIZE(szName), szName))
  70. {
  71. dwFlags = FLAG_HELP;
  72. }
  73. }
  74. if (!dwFlags)
  75. {
  76. dwFlags = FLAG_FILE;
  77. }
  78. if (dwFlags & FLAG_HELP)
  79. {
  80. dwFlags = FLAG_HELP;
  81. }
  82. if (dwFlags & FLAG_DEBUG)
  83. {
  84. _tprintf(TEXT("DBG: %d\n"), argc);
  85. for (int i = 0; i < argc; ++i)
  86. _tprintf(TEXT("DBG: Arg #%d is \"%s\"\n"), i, argv[i]);
  87. _tprintf(TEXT("DBG: Flags\n"));
  88. for (DWORD j = 0; j < 32; ++j)
  89. {
  90. DWORD dw = 1 << j;
  91. if (dw & dwFlags)
  92. {
  93. _tprintf(TEXT("\n DBG: "));
  94. switch (dw)
  95. {
  96. PRINTCASE(FLAG_HELP );
  97. PRINTCASE(FLAG_DEBUG );
  98. PRINTCASE(FLAG_DRIVE );
  99. PRINTCASE(FLAG_FILE );
  100. PRINTCASE(FLAG_NETWORK );
  101. PRINTCASE(FLAG_LOGDRIVE );
  102. PRINTCASE(FLAG_MOUNTPOINT );
  103. PRINTCASE(FLAG_VOLUMEGUID );
  104. }
  105. }
  106. }
  107. }
  108. if (dwFlags & FLAG_HELP)
  109. {
  110. _tprintf(TEXT("\nDRV [/F] [/D] [/B] [/?] [path]"));
  111. _tprintf(TEXT("\n\n [path]"));
  112. _tprintf(TEXT("\n Specifies a drive, file, drive mounted on a folder, or Volume GUID."));
  113. _tprintf(TEXT("\n\n /F Retrieves file information (GetFileAttributes)."));
  114. _tprintf(TEXT("\n /D Retrieves drive information (GetDriveType + GetVolumeInformation)."));
  115. _tprintf(TEXT("\n /N Retrieves Network share information (WNetGetConnection)"));
  116. _tprintf(TEXT("\n /L Retrieves Logical drives info (GetLogicalDrives)"));
  117. _tprintf(TEXT("\n /B Dumps debug info."));
  118. _tprintf(TEXT("\n /? Displays this message."));
  119. _tprintf(TEXT("\n\nIf no switches are provided, '/F' is assumed. For mounted volumes on\nfolder problems, try appending a backslash.\n\n(Source code: shell\\tools\\drv)"));
  120. }
  121. else
  122. {
  123. _tprintf(TEXT("\n---------------------------------------------------\n--- For: \"%s\""), szName);
  124. }
  125. if (dwFlags & FLAG_FILE)
  126. {
  127. // GetFileAttributes
  128. {
  129. _tprintf(TEXT("\n............................................................."));
  130. _tprintf(TEXT("\n... GetFileAttributes()\n"));
  131. DWORD dwFA = GetFileAttributes(szName);
  132. _tprintf(TEXT("\n Return Value: 0x%08X"), dwFA);
  133. if (0xFFFFFFFF != dwFA)
  134. {
  135. for (DWORD i = 0; i < 32; ++i)
  136. {
  137. DWORD dw = 1 << i;
  138. if (dw & dwFA)
  139. {
  140. _tprintf(TEXT("\n "));
  141. switch (dw)
  142. {
  143. PRINTCASE(FILE_ATTRIBUTE_READONLY );
  144. PRINTCASE(FILE_ATTRIBUTE_HIDDEN );
  145. PRINTCASE(FILE_ATTRIBUTE_SYSTEM );
  146. PRINTCASE(FILE_ATTRIBUTE_DIRECTORY );
  147. PRINTCASE(FILE_ATTRIBUTE_ARCHIVE );
  148. PRINTCASE(FILE_ATTRIBUTE_DEVICE );
  149. PRINTCASE(FILE_ATTRIBUTE_NORMAL );
  150. PRINTCASE(FILE_ATTRIBUTE_TEMPORARY );
  151. PRINTCASE(FILE_ATTRIBUTE_SPARSE_FILE );
  152. PRINTCASE(FILE_ATTRIBUTE_REPARSE_POINT );
  153. PRINTCASE(FILE_ATTRIBUTE_COMPRESSED );
  154. PRINTCASE(FILE_ATTRIBUTE_OFFLINE );
  155. PRINTCASE(FILE_ATTRIBUTE_NOT_CONTENT_INDEXED);
  156. PRINTCASE(FILE_ATTRIBUTE_ENCRYPTED );
  157. default:
  158. _tprintf(TEXT(" %08X"), i);
  159. break;
  160. }
  161. }
  162. }
  163. }
  164. }
  165. }
  166. if (dwFlags & FLAG_DRIVE)
  167. {
  168. // GetDriveType
  169. {
  170. _tprintf(TEXT("\n............................................................."));
  171. _tprintf(TEXT("\n... GetDriveType()\n"));
  172. UINT u = GetDriveType(szName);
  173. _tprintf(TEXT("\n Return Value: 0x%08X"), u);
  174. _tprintf(TEXT("\n "));
  175. switch (u)
  176. {
  177. PRINTCASE(DRIVE_UNKNOWN);
  178. PRINTCASE(DRIVE_NO_ROOT_DIR);
  179. PRINTCASE(DRIVE_REMOVABLE);
  180. PRINTCASE(DRIVE_FIXED);
  181. PRINTCASE(DRIVE_REMOTE);
  182. PRINTCASE(DRIVE_CDROM);
  183. PRINTCASE(DRIVE_RAMDISK);
  184. }
  185. }
  186. }
  187. if (dwFlags & FLAG_DRIVE)
  188. {
  189. // GetVolumeInformation
  190. {
  191. _tprintf(TEXT("\n............................................................."));
  192. _tprintf(TEXT("\n... GetVolumeInformation()\n"));
  193. {
  194. TCHAR szVolumeName[MAX_PATH];
  195. DWORD dwVolSerialNumber;
  196. DWORD dwMaxCompName;
  197. DWORD dwFileSysFlags;
  198. TCHAR szFileSysName[MAX_PATH];
  199. BOOL b = GetVolumeInformation(
  200. szName,
  201. szVolumeName,
  202. MAX_PATH,
  203. &dwVolSerialNumber,
  204. &dwMaxCompName,
  205. &dwFileSysFlags,
  206. szFileSysName,
  207. MAX_PATH);
  208. _tprintf(TEXT("\n Return Value: 0x%08X"), b);
  209. if (!b)
  210. {
  211. _tprintf(TEXT(" (FALSE)"));
  212. }
  213. else
  214. {
  215. if (TRUE == b)
  216. {
  217. _tprintf(TEXT(" (TRUE)"));
  218. }
  219. _tprintf(TEXT("\n Volume Name: \"%s\""), szVolumeName);
  220. _tprintf(TEXT("\n Volume Serial#: %04X-%04X"), HIWORD(dwVolSerialNumber),
  221. LOWORD(dwVolSerialNumber));
  222. _tprintf(TEXT("\n Volume Max Comp Name: %d"), dwMaxCompName);
  223. _tprintf(TEXT("\n File System Name: \"%s\""), szFileSysName);
  224. _tprintf(TEXT("\n File System Flags:"));
  225. for (DWORD i = 0; i < 32; ++i)
  226. {
  227. DWORD dw = 1 << i;
  228. if (dw & dwFileSysFlags)
  229. {
  230. _tprintf(TEXT("\n "));
  231. switch (dw)
  232. {
  233. PRINTCASE(FILE_CASE_SENSITIVE_SEARCH );
  234. PRINTCASE(FILE_CASE_PRESERVED_NAMES );
  235. PRINTCASE(FILE_UNICODE_ON_DISK );
  236. PRINTCASE(FILE_PERSISTENT_ACLS );
  237. PRINTCASE(FILE_FILE_COMPRESSION );
  238. PRINTCASE(FILE_VOLUME_QUOTAS );
  239. PRINTCASE(FILE_SUPPORTS_SPARSE_FILES );
  240. PRINTCASE(FILE_SUPPORTS_REPARSE_POINTS);
  241. PRINTCASE(FILE_SUPPORTS_REMOTE_STORAGE);
  242. PRINTCASE(FILE_VOLUME_IS_COMPRESSED );
  243. PRINTCASE(FILE_SUPPORTS_OBJECT_IDS );
  244. PRINTCASE(FILE_SUPPORTS_ENCRYPTION );
  245. default:
  246. _tprintf(TEXT(" %08X"), i);
  247. break;
  248. }
  249. }
  250. }
  251. }
  252. }
  253. }
  254. }
  255. if (dwFlags & FLAG_NETWORK)
  256. {
  257. TCHAR szRemote[MAX_PATH];
  258. lstrcpyn(szRemote, szName, ARRAYSIZE(szRemote));
  259. szRemote[2] = 0;
  260. {
  261. _tprintf(TEXT("\n............................................................."));
  262. _tprintf(TEXT("\n... WNetGetConnection()\n"));
  263. TCHAR szRemoteName[MAX_PATH];
  264. DWORD cchRemoteName = ARRAYSIZE(szRemoteName);
  265. DWORD dw = WNetGetConnection(szRemote, szRemoteName, &cchRemoteName);
  266. _tprintf(TEXT("\n Return Value: 0x%08X ("), dw);
  267. switch (dw)
  268. {
  269. PRINTCASE(NO_ERROR );
  270. PRINTCASE(WN_NOT_CONNECTED );
  271. PRINTCASE(WN_OPEN_FILES );
  272. PRINTCASE(WN_DEVICE_IN_USE );
  273. PRINTCASE(WN_BAD_NETNAME );
  274. PRINTCASE(WN_BAD_LOCALNAME );
  275. PRINTCASE(WN_ALREADY_CONNECTED );
  276. PRINTCASE(WN_DEVICE_ERROR );
  277. PRINTCASE(WN_CONNECTION_CLOSED );
  278. PRINTCASE(WN_NO_NET_OR_BAD_PATH );
  279. PRINTCASE(WN_BAD_PROVIDER );
  280. PRINTCASE(WN_CANNOT_OPEN_PROFILE );
  281. PRINTCASE(WN_BAD_PROFILE );
  282. PRINTCASE(WN_BAD_DEV_TYPE );
  283. PRINTCASE(WN_DEVICE_ALREADY_REMEMBERED );
  284. PRINTCASE(WN_CONNECTED_OTHER_PASSWORD );
  285. }
  286. if (WN_CONNECTION_CLOSED == dw)
  287. {
  288. _tprintf(TEXT(" == ERROR_CONNECTION_UNAVAIL)"));
  289. }
  290. else
  291. {
  292. _tprintf(TEXT(")"));
  293. }
  294. if (NO_ERROR == dw)
  295. {
  296. _tprintf(TEXT("\n RemoteName: \"%s\""), szRemoteName);
  297. }
  298. }
  299. {
  300. _tprintf(TEXT("\n\n............................................................."));
  301. _tprintf(TEXT("\n... WNetGetConnection3(..., WNGC_INFOLEVEL_DISCONNECTED, ...)\n"));
  302. WNGC_CONNECTION_STATE wngc;
  303. DWORD dwSize = sizeof(wngc.dwState);
  304. DWORD dw = WNetGetConnection3(szRemote, NULL, WNGC_INFOLEVEL_DISCONNECTED,
  305. &wngc.dwState, &dwSize);
  306. _tprintf(TEXT("\n Return Value: 0x%08X ("), dw);
  307. switch (dw)
  308. {
  309. PRINTCASE(NO_ERROR );
  310. PRINTCASE(WN_NOT_CONNECTED );
  311. PRINTCASE(WN_OPEN_FILES );
  312. PRINTCASE(WN_DEVICE_IN_USE );
  313. PRINTCASE(WN_BAD_NETNAME );
  314. PRINTCASE(WN_BAD_LOCALNAME );
  315. PRINTCASE(WN_ALREADY_CONNECTED );
  316. PRINTCASE(WN_DEVICE_ERROR );
  317. PRINTCASE(WN_CONNECTION_CLOSED );
  318. PRINTCASE(WN_NO_NET_OR_BAD_PATH );
  319. PRINTCASE(WN_BAD_PROVIDER );
  320. PRINTCASE(WN_CANNOT_OPEN_PROFILE );
  321. PRINTCASE(WN_BAD_PROFILE );
  322. PRINTCASE(WN_BAD_DEV_TYPE );
  323. PRINTCASE(WN_DEVICE_ALREADY_REMEMBERED );
  324. PRINTCASE(WN_CONNECTED_OTHER_PASSWORD );
  325. }
  326. if (WN_CONNECTION_CLOSED == dw)
  327. {
  328. _tprintf(TEXT(" == ERROR_CONNECTION_UNAVAIL)"));
  329. }
  330. else
  331. {
  332. _tprintf(TEXT(")"));
  333. }
  334. if (NO_ERROR == dw)
  335. {
  336. _tprintf(TEXT("\n CONNECTIONSTATUS.dwState: 0x%08X ("), wngc.dwState);
  337. switch (wngc.dwState)
  338. {
  339. PRINTCASE(WNGC_CONNECTED);
  340. PRINTCASE(WNGC_DISCONNECTED);
  341. }
  342. _tprintf(TEXT(")"));
  343. }
  344. }
  345. }
  346. if (dwFlags & FLAG_LOGDRIVE)
  347. {
  348. _tprintf(TEXT("\n\n............................................................."));
  349. _tprintf(TEXT("\n... GetLogicalDrives()\n"));
  350. DWORD dwLG = GetLogicalDrives();
  351. _tprintf(TEXT("\n Return Value: 0x%08X"), dwLG);
  352. for (DWORD i = 0; i < 32; ++i)
  353. {
  354. DWORD dw = 1 << i;
  355. if (dw & dwLG)
  356. {
  357. _tprintf(TEXT("\n %c:"), TEXT('A') + (TCHAR)i);
  358. }
  359. }
  360. }
  361. _tprintf(TEXT("\n"));
  362. return 0;
  363. }
  364. #ifdef UNICODE
  365. }
  366. #endif