Leaked source code of windows server 2003
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.

679 lines
19 KiB

  1. #include "brian.h"
  2. typedef struct _ASYNC_SET_VOLUME {
  3. USHORT FileIndex;
  4. FILE_INFORMATION_CLASS FileInfoClass;
  5. ULONG BufferLength;
  6. PULONG BufferLengthPtr;
  7. ULONG LabelLength;
  8. PULONG LabelLengthPtr;
  9. USHORT LabelIndex;
  10. BOOLEAN LabelBufferAllocated;
  11. BOOLEAN DisplayParms;
  12. BOOLEAN VerboseResults;
  13. USHORT AsyncIndex;
  14. } ASYNC_SET_VOLUME, *PASYNC_SET_VOLUME;
  15. #define SET_VOLUME_LENGTH_DEFAULT 100
  16. #define FILE_INFO_CLASS_DEFAULT FileFsLabelInformation
  17. #define DISPLAY_PARMS_DEFAULT FALSE
  18. #define VERBOSE_DEFAULT FALSE
  19. VOID
  20. FullSetVolume(
  21. IN OUT PASYNC_SET_VOLUME AsyncSetVolume
  22. );
  23. VOID
  24. SetFsLabelInformation(
  25. IN OUT PASYNC_SET_VOLUME AsyncSetVolume
  26. );
  27. VOID
  28. InputSetVolume (
  29. IN PCHAR ParamBuffer
  30. )
  31. {
  32. USHORT FileIndex;
  33. FILE_INFORMATION_CLASS FileInfoClass;
  34. ULONG BufferLength;
  35. PULONG BufferLengthPtr;
  36. ANSI_STRING AnsiLabelString;
  37. ULONG LabelLength;
  38. PULONG LabelLengthPtr;
  39. USHORT LabelIndex;
  40. BOOLEAN LabelBufferAllocated;
  41. PUCHAR LabelPtr;
  42. BOOLEAN DisplayParms;
  43. BOOLEAN VerboseResults;
  44. USHORT AsyncIndex;
  45. BOOLEAN ParamReceived;
  46. BOOLEAN LastInput;
  47. //
  48. // Set the defaults.
  49. //
  50. FileInfoClass = FILE_INFO_CLASS_DEFAULT;
  51. BufferLengthPtr = NULL;
  52. LabelLengthPtr = NULL;
  53. LabelBufferAllocated = FALSE;
  54. LabelPtr = NULL;
  55. DisplayParms = DISPLAY_PARMS_DEFAULT;
  56. VerboseResults = VERBOSE_DEFAULT;
  57. ParamReceived = FALSE;
  58. LastInput = TRUE;
  59. //
  60. // While there is more input, analyze the parameter and update the
  61. // query flags.
  62. //
  63. while (TRUE) {
  64. ULONG DummyCount;
  65. //
  66. // Swallow leading white spaces.
  67. //
  68. ParamBuffer = SwallowWhite( ParamBuffer, &DummyCount );
  69. if (*ParamBuffer) {
  70. //
  71. // If the next parameter is legal then check the paramter value.
  72. // Update the parameter value.
  73. //
  74. if ((*ParamBuffer == '-'
  75. || *ParamBuffer == '/')
  76. && (ParamBuffer++, *ParamBuffer != '\0')) {
  77. BOOLEAN SwitchBool;
  78. //
  79. // Switch on the next character.
  80. //
  81. switch (*ParamBuffer) {
  82. //
  83. // Update the byte count.
  84. //
  85. case 'l' :
  86. case 'L' :
  87. //
  88. // Move to the next character, as long as there
  89. // are no white spaces continue analyzing letters.
  90. // On the first bad letter, skip to the next
  91. // parameter.
  92. //
  93. ParamBuffer++;
  94. if (*ParamBuffer == '\0') {
  95. break;
  96. }
  97. switch (*ParamBuffer) {
  98. case 'b':
  99. case 'B':
  100. BufferLength = AsciiToInteger( ++ParamBuffer );
  101. BufferLengthPtr = &BufferLength;
  102. break;
  103. case 'l':
  104. case 'L':
  105. LabelLength = AsciiToInteger( ++ParamBuffer );
  106. LabelLengthPtr = &LabelLength;
  107. break;
  108. }
  109. ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
  110. break;
  111. //
  112. // Update the label name.
  113. //
  114. case 'f' :
  115. case 'F' :
  116. //
  117. // Move to the next character, as long as there
  118. // are no white spaces continue analyzing letters.
  119. // On the first bad letter, skip to the next
  120. // parameter.
  121. //
  122. ParamBuffer++;
  123. if (*ParamBuffer == '\0') {
  124. break;
  125. }
  126. switch (*ParamBuffer) {
  127. PUCHAR TempPtr;
  128. case 'l':
  129. case 'L':
  130. //
  131. // Remember the buffer offset and get the filename.
  132. //
  133. ParamBuffer++;
  134. TempPtr = ParamBuffer;
  135. DummyCount = 0;
  136. ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
  137. //
  138. // If the name length is 0, then ignore this entry.
  139. //
  140. if (DummyCount) {
  141. AnsiLabelString.Length = (USHORT) DummyCount;
  142. AnsiLabelString.Buffer = TempPtr;
  143. LabelPtr = TempPtr;
  144. LabelLength = (ULONG) RtlAnsiStringToUnicodeSize( &AnsiLabelString) - sizeof( WCHAR );
  145. LabelLengthPtr = &LabelLength;
  146. }
  147. break;
  148. }
  149. ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
  150. break;
  151. //
  152. // Update the file handle index.
  153. //
  154. case 'i' :
  155. case 'I' :
  156. //
  157. // Move to the next character, as long as there
  158. // are no white spaces continue analyzing letters.
  159. // On the first bad letter, skip to the next
  160. // parameter.
  161. //
  162. ParamBuffer++;
  163. FileIndex = (USHORT) AsciiToInteger( ParamBuffer );
  164. ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
  165. ParamReceived = TRUE;
  166. break;
  167. //
  168. // Update the information class.
  169. //
  170. case 'c' :
  171. case 'C' :
  172. //
  173. // Move to the next character, as long as there
  174. // are no white spaces continue analyzing letters.
  175. // On the first bad letter, skip to the next
  176. // parameter.
  177. //
  178. ParamBuffer++;
  179. SwitchBool = TRUE;
  180. while (*ParamBuffer
  181. && *ParamBuffer != ' '
  182. && *ParamBuffer != '\t') {
  183. //
  184. // Perform switch on character.
  185. //
  186. switch (*ParamBuffer) {
  187. case 'a' :
  188. case 'A' :
  189. FileInfoClass = FileFsLabelInformation;
  190. break;
  191. default :
  192. ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
  193. SwitchBool = FALSE;
  194. }
  195. if (!SwitchBool) {
  196. break;
  197. }
  198. ParamBuffer++;
  199. }
  200. break;
  201. case 'v' :
  202. case 'V' :
  203. //
  204. // Legal values for params are T/t or F/f.
  205. //
  206. ParamBuffer++;
  207. if( *ParamBuffer == 'T'
  208. || *ParamBuffer == 't' ) {
  209. VerboseResults = TRUE;
  210. ParamBuffer++;
  211. } else if( *ParamBuffer == 'F'
  212. || *ParamBuffer == 'f' ) {
  213. VerboseResults = FALSE;
  214. ParamBuffer++;
  215. }
  216. break;
  217. case 'y' :
  218. case 'Y' :
  219. //
  220. // Set the display parms flag and jump over this
  221. // character.
  222. //
  223. DisplayParms = TRUE;
  224. ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
  225. break;
  226. case 'z' :
  227. case 'Z' :
  228. //
  229. // Set flag for more input and jump over this char.
  230. //
  231. LastInput = FALSE;
  232. ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
  233. break;
  234. default :
  235. //
  236. // Swallow to the next white space and continue the
  237. // loop.
  238. //
  239. ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
  240. }
  241. }
  242. //
  243. // Else the text is invalid, skip the entire block.
  244. //
  245. //
  246. //
  247. // Else if there is no input then exit.
  248. //
  249. } else if( LastInput ) {
  250. break;
  251. //
  252. // Else try to read another line for open parameters.
  253. //
  254. } else {
  255. }
  256. }
  257. //
  258. // If no parameters were received then display the syntax message.
  259. //
  260. if (!ParamReceived) {
  261. printf( "\n Usage: sv [options]* -i<index> [options]*\n" );
  262. printf( "\n Options:" );
  263. printf( "\n -i<digits> File index" );
  264. printf( "\n -lb<digits> Buffer length" );
  265. printf( "\n -c<char> File information class" );
  266. printf( "\n -fl<name> Name for label" );
  267. printf( "\n -ll<digits> Stated length of label" );
  268. printf( "\n -v[t|f] Verbose results" );
  269. printf( "\n -y Display parameters to query" );
  270. printf( "\n -z Additional input line" );
  271. printf( "\n\n" );
  272. //
  273. // Else call our read routine.
  274. //
  275. } else {
  276. NTSTATUS Status;
  277. SIZE_T RegionSize;
  278. ULONG TempIndex;
  279. PASYNC_SET_VOLUME AsyncSetVolume;
  280. HANDLE ThreadHandle;
  281. ULONG ThreadId;
  282. RegionSize = sizeof( ASYNC_SET_VOLUME );
  283. Status = AllocateBuffer( 0, &RegionSize, &TempIndex );
  284. AsyncIndex = (USHORT) TempIndex;
  285. if (!NT_SUCCESS( Status )) {
  286. printf("\n\tInputSetFile: Unable to allocate async structure" );
  287. } else {
  288. UNICODE_STRING UnicodeString;
  289. //
  290. // If we need a buffer for the label, allocate it now.
  291. //
  292. if (LabelPtr == NULL) {
  293. RtlInitAnsiString( &AnsiLabelString, "" );
  294. LabelPtr = AnsiLabelString.Buffer;
  295. LabelLength = 100;
  296. }
  297. RegionSize = LabelLength;
  298. Status = AllocateBuffer( 0, &RegionSize, &TempIndex );
  299. if (!NT_SUCCESS( Status )) {
  300. printf( "\n\tInputSetVolume: Unable to allocate label structure" );
  301. DeallocateBuffer( AsyncIndex );
  302. return;
  303. }
  304. UnicodeString.Buffer = (PWSTR) Buffers[TempIndex].Buffer;
  305. UnicodeString.MaximumLength = (USHORT) Buffers[TempIndex].Length;
  306. LabelIndex = (USHORT) TempIndex;
  307. LabelBufferAllocated = TRUE;
  308. //
  309. // Store the name in the buffer.
  310. //
  311. RtlAnsiStringToUnicodeString( &UnicodeString,
  312. &AnsiLabelString,
  313. FALSE );
  314. AsyncSetVolume = (PASYNC_SET_VOLUME) Buffers[AsyncIndex].Buffer;
  315. AsyncSetVolume->FileIndex = (USHORT) FileIndex;
  316. AsyncSetVolume->BufferLength = BufferLength;
  317. AsyncSetVolume->BufferLengthPtr = BufferLengthPtr ?
  318. &AsyncSetVolume->BufferLength :
  319. NULL;
  320. AsyncSetVolume->FileInfoClass = FileInfoClass;
  321. AsyncSetVolume->LabelLength = LabelLength;
  322. AsyncSetVolume->LabelLengthPtr = LabelLengthPtr
  323. ? &AsyncSetVolume->LabelLength
  324. : NULL;
  325. AsyncSetVolume->LabelIndex = LabelIndex;
  326. AsyncSetVolume->LabelBufferAllocated = LabelBufferAllocated;
  327. AsyncSetVolume->DisplayParms = DisplayParms;
  328. AsyncSetVolume->VerboseResults = VerboseResults;
  329. AsyncSetVolume->AsyncIndex = AsyncIndex;
  330. if (!SynchronousCmds) {
  331. ThreadHandle = CreateThread( NULL,
  332. 0,
  333. FullSetVolume,
  334. AsyncSetVolume,
  335. 0,
  336. &ThreadId );
  337. if (ThreadHandle == 0) {
  338. printf( "\nInputSetVolume: Spawning thread fails -> %d\n", GetLastError() );
  339. if (LabelBufferAllocated) {
  340. DeallocateBuffer( LabelIndex );
  341. }
  342. DeallocateBuffer( AsyncIndex );
  343. return;
  344. }
  345. } else {
  346. FullSetVolume( AsyncSetVolume );
  347. }
  348. }
  349. }
  350. return;
  351. }
  352. VOID
  353. FullSetVolume(
  354. IN OUT PASYNC_SET_VOLUME AsyncSetVolume
  355. )
  356. {
  357. try {
  358. //
  359. // Case on the information type and call the appropriate routine.
  360. //
  361. switch (AsyncSetVolume->FileInfoClass) {
  362. case FileFsLabelInformation:
  363. SetFsLabelInformation( AsyncSetVolume );
  364. break;
  365. default:
  366. bprint "\nFullSetVolume: Unrecognized information class\n" );
  367. }
  368. try_return( NOTHING );
  369. try_exit: NOTHING;
  370. } finally {
  371. if (AsyncSetVolume->LabelBufferAllocated) {
  372. DeallocateBuffer( AsyncSetVolume->LabelIndex );
  373. }
  374. DeallocateBuffer( AsyncSetVolume->AsyncIndex );
  375. }
  376. if (!SynchronousCmds) {
  377. NtTerminateThread( 0, STATUS_SUCCESS );
  378. }
  379. }
  380. VOID
  381. SetFsLabelInformation(
  382. IN OUT PASYNC_SET_VOLUME AsyncSetVolume
  383. )
  384. {
  385. NTSTATUS Status;
  386. PFILE_FS_LABEL_INFORMATION LabelInformation;
  387. USHORT BufferIndex;
  388. UNICODE_STRING UniLabel;
  389. ANSI_STRING AnsiLabel;
  390. BOOLEAN UnwindBufferIndex = FALSE;
  391. BOOLEAN UnwindFreeAnsiString = FALSE;
  392. //
  393. // Check that there is a label specified.
  394. //
  395. if (!AsyncSetVolume->LabelBufferAllocated) {
  396. bprint "\nSet Label Information: No label was specified\n" );
  397. return;
  398. }
  399. UniLabel.Buffer = (PWSTR) Buffers[AsyncSetVolume->LabelIndex].Buffer;
  400. UniLabel.MaximumLength =
  401. UniLabel.Length = (USHORT) AsyncSetVolume->LabelLength;
  402. UniLabel.MaximumLength += 2;
  403. Status = RtlUnicodeStringToAnsiString( &AnsiLabel,
  404. &UniLabel,
  405. TRUE );
  406. if (!NT_SUCCESS( Status )) {
  407. bprint "\nSetLabelInfo: Can't allocate ansi buffer -> %08lx\n", Status );
  408. AsyncSetVolume->DisplayParms = FALSE;
  409. } else {
  410. UnwindFreeAnsiString = TRUE;
  411. }
  412. if (AsyncSetVolume->DisplayParms) {
  413. bprint "\nSet LabelInformation Parameters" );
  414. bprint "\n File Handle Index -> %d", AsyncSetVolume->FileIndex );
  415. bprint "\n BufferLengthPtr -> %08lx", AsyncSetVolume->BufferLengthPtr );
  416. if (AsyncSetVolume->BufferLengthPtr) {
  417. bprint "\n BufferLength value -> %08x", AsyncSetVolume->BufferLength );
  418. }
  419. bprint "\n Label length -> %d", AsyncSetVolume->LabelLength );
  420. bprint "\n New label -> %s", AnsiLabel.Buffer );
  421. bprint "\n\n" );
  422. }
  423. try {
  424. SIZE_T RegionSize;
  425. ULONG TempIndex;
  426. IO_STATUS_BLOCK Iosb;
  427. RegionSize = sizeof( FILE_FS_LABEL_INFORMATION ) + AsyncSetVolume->LabelLength;
  428. Status = AllocateBuffer( 0, &RegionSize, &TempIndex );
  429. BufferIndex = (USHORT) TempIndex;
  430. if (!NT_SUCCESS( Status )) {
  431. bprint "\n\tSetLabelInformation: Unable to allocate structure" );
  432. try_return( NOTHING );
  433. }
  434. UnwindBufferIndex = TRUE;
  435. LabelInformation = (PFILE_FS_LABEL_INFORMATION) Buffers[BufferIndex].Buffer;
  436. //
  437. // Fill in the new information.
  438. //
  439. LabelInformation->VolumeLabelLength = AsyncSetVolume->LabelLength;
  440. RtlMoveMemory( LabelInformation->VolumeLabel,
  441. UniLabel.Buffer,
  442. AsyncSetVolume->LabelLength );
  443. Iosb.Status = STATUS_SUCCESS;
  444. Iosb.Information = 0;
  445. Status = NtSetVolumeInformationFile( Handles[AsyncSetVolume->FileIndex].Handle,
  446. &Iosb,
  447. LabelInformation,
  448. AsyncSetVolume->BufferLengthPtr
  449. ? AsyncSetVolume->BufferLength
  450. : Buffers[BufferIndex].Length,
  451. FileFsLabelInformation );
  452. if (AsyncSetVolume->VerboseResults) {
  453. bprint "\nSetInformationFile: Status -> %08lx", Status );
  454. if (NT_SUCCESS( Status )) {
  455. bprint "\n Iosb.Information -> %08lx", Iosb.Information );
  456. bprint "\n Iosb.Status -> %08lx", Iosb.Status );
  457. }
  458. bprint "\n" );
  459. }
  460. try_exit: NOTHING;
  461. } finally {
  462. if (UnwindFreeAnsiString) {
  463. RtlFreeAnsiString( &AnsiLabel );
  464. }
  465. if (UnwindBufferIndex) {
  466. DeallocateBuffer( BufferIndex );
  467. }
  468. }
  469. return;
  470. }