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.

506 lines
15 KiB

  1. '-------------------------------------------------------------------
  2. ' Microsoft Windows
  3. '
  4. ' Copyright (C) Microsoft Corporation, 1997 - 1999
  5. '
  6. ' File: dskquota.vbs
  7. '
  8. ' This file is a VBScript for testing the scripting features of
  9. ' the Windows 2000 disk quota interface code. It also serves as
  10. ' an example of how to properly use the disk quota objects
  11. ' with scripting.
  12. '
  13. ' It's designed to accept /<cmd>=<value> arguments so that all
  14. ' of the scripting features can be tested using the same utility.
  15. ' It however wasn't written to be very tolerant of bad input.
  16. ' For instance, a command must be preceded by a '/' character.
  17. ' An '=' character must separate the command and value.
  18. ' No spaces are tolerated between the '/', <cmd>, '=' and <value>.
  19. '
  20. ' This is valid:
  21. '
  22. ' dskquota /volume=e: /showuser=redmond\brianau
  23. '
  24. ' This is not:
  25. '
  26. ' dskquota /volume= e: /showuser = redmond\brianau
  27. '
  28. ' Multiple commands can appear in the same invocation. The following
  29. ' command will display quota information for both the volume and a
  30. ' user.
  31. '
  32. ' dskquota /volume=e: /show /showuser=redmond\brianau
  33. '
  34. ' Here's a summary of the available commands:
  35. '
  36. ' /VOLUME=<volume id>
  37. '
  38. ' This command is required. <volume id> identifies the volume.
  39. ' i.e. "E:"
  40. '
  41. ' /STATE=<DISABLE | TRACK | ENFORCE>
  42. '
  43. ' Enables or disables quotas on the volume.
  44. ' DISABLE disables quotas.
  45. ' TRACK enables quotas but doesn't enforce quota limits.
  46. ' ENFORCE enables quotas and enforces quota limits.
  47. '
  48. ' /NAMERES=<NONE | SYNC | ASYNC>
  49. '
  50. ' Sets the user-name synchronization mode for the current
  51. ' invocation only. Since Async name resolution is meaningless
  52. ' for a command-line script, this command use most useful for
  53. ' testing the ability to set the name resolution mode.
  54. ' The following command could be used to verify proper operation:
  55. '
  56. ' dskquota /volume=e: /nameres=sync /show
  57. '
  58. ' The output of /SHOW would be used to verify the correct resolution
  59. ' setting.
  60. '
  61. ' NONE means that a name must be cached to be returned.
  62. ' SYNC means that any function returning a non-cached name
  63. ' will block until that name is resolved. This is the
  64. ' default.
  65. ' ASYNC means that any function returning a non-cached name
  66. ' will return immediately. The name resolution connection
  67. ' point is used to obtain the name asynchronously once
  68. ' it has been resolved. This has no purpose in a cmd line
  69. ' script.
  70. '
  71. ' /DEFLIMIT=<bytes>
  72. '
  73. ' Sets the default quota limit on the volume.
  74. '
  75. ' /DEFWARNING=<bytes>
  76. '
  77. ' Sets the default quota warning level on the volume.
  78. '
  79. ' /SHOW
  80. '
  81. ' Displays a summary of volume-specific quota information.
  82. '
  83. ' /SHOWUSER=<user logon name>
  84. '
  85. ' Displays a summary of user-specific quota information if there's
  86. ' a record for the user in the volume's quota file. Specify '*'
  87. ' for <user logon name> to enumerate all user quota records.
  88. '
  89. ' dskquota /volume=e: /showuser=redmond\brianau
  90. ' dskquota /volume=e: /showuser=*
  91. '
  92. ' /LOGLIMIT=<YES | NO>
  93. '
  94. ' Enables/disables system logging of users who exceed their
  95. ' assigned quota limit.
  96. '
  97. ' /LOGWARNING=<YES | NO>
  98. '
  99. ' Enables/disables system logging of users who exceed their
  100. ' assigned quota warning threshold.
  101. '
  102. ' /ADDUSER=<user logon name>
  103. '
  104. ' Adds a new user record to the volume's quota file. The new record
  105. ' has assigned to it the default limit and warning threshold for
  106. ' the volume.
  107. '
  108. ' dskquota /volume=e: /adduser=redmond\brianau
  109. '
  110. ' /DELUSER=<user logon name>
  111. '
  112. ' Removes a user's quota record from the volume's quota file.
  113. ' In actuality, this merely marks the record for deletion. Actual
  114. ' deletion occurs later when NTFS rebuilds the volume's quota info.
  115. '
  116. ' /USER=<user logon name>
  117. '
  118. ' Specifies the user record associated with a /LIMIT or /WARNING
  119. ' command.
  120. '
  121. ' dskquota /volume=e: /user=redmond\brianau /limit=1048576
  122. '
  123. ' /LIMIT=<bytes>
  124. '
  125. ' Sets the quota limit for a user's quota record. Must be accompanied
  126. ' by the /USER command.
  127. '
  128. ' /WARNING=<bytes>
  129. '
  130. ' Sets the quota warning level for a user's quota record. Must be
  131. ' accompanied by the /USER command.
  132. '
  133. '-------------------------------------------------------------------
  134. '
  135. ' Name Resolution type names.
  136. '
  137. DIM rgstrNameRes(3)
  138. rgstrNameRes(0) = "NONE" ' No name resolution.
  139. rgstrNameRes(1) = "SYNC" ' Synchronous name resolution.
  140. rgstrNameRes(2) = "ASYNC" ' Asynchronous name resolution.
  141. '
  142. ' Volume quota state names.
  143. '
  144. DIM rgstrStateNames(3)
  145. rgstrStateNames(0) = "DISABLE" ' Quotas are disabled.
  146. rgstrStateNames(1) = "TRACK" ' Enabled but not enforced.
  147. rgstrStateNames(2) = "ENFORCE" ' Enabled AND enforced.
  148. '
  149. ' Generic YES/NO name strings.
  150. '
  151. DIM rgstrYesNo(2)
  152. rgstrYesNo(0) = "NO"
  153. rgstrYesNo(1) = "YES"
  154. '
  155. ' Define an array index for each cmdline argument.
  156. '
  157. iArgVolume = 0 ' /VOLUME=<volumeid>
  158. iArgState = 1 ' /STATE=<DISABLE | TRACK | ENFORCE>
  159. iArgNameRes = 2 ' /NAMERES=<NONE | SYNC | ASYNC>
  160. iArgDefLimit = 3 ' /DEFLIMIT=<bytes>
  161. iArgDefWarning = 4 ' /DEFWARNING=<bytes>
  162. iArgShow = 5 ' /SHOW
  163. iArgLogLimit = 6 ' /LOGLIMIT=<YES | NO>
  164. iArgLogWarning = 7 ' /LOGWARNING=<YES | NO>
  165. iArgShowUser = 8 ' /SHOWUSER=<user logon name>
  166. iArgAddUser = 9 ' /ADDUSER=<user logon name>
  167. iArgDelUser = 10 ' /DELUSER=<user logon name>
  168. iArgUser = 11 ' /USER=<user logon name>
  169. iArgLimit = 12 ' /LIMIT=<bytes>
  170. iArgWarning = 13 ' /WARNING=<bytes>
  171. '
  172. ' Define an array of argument names.
  173. '
  174. DIM rgstrArgNames(14)
  175. rgstrArgNames(0) = "VOLUME"
  176. rgstrArgNames(1) = "STATE"
  177. rgstrArgNames(2) = "NAMERES"
  178. rgstrArgNames(3) = "DEFLIMIT"
  179. rgstrArgNames(4) = "DEFWARNING"
  180. rgstrArgNames(5) = "SHOW"
  181. rgstrArgNames(6) = "LOGLIMIT"
  182. rgstrArgNames(7) = "LOGWARNING"
  183. rgstrArgNames(8) = "SHOWUSER"
  184. rgstrArgNames(9) = "ADDUSER"
  185. rgstrArgNames(10) = "DELUSER"
  186. rgstrArgNames(11) = "USER"
  187. rgstrArgNames(12) = "LIMIT"
  188. rgstrArgNames(13) = "WARNING"
  189. '
  190. ' Define an array to hold argument values.
  191. ' The length must be the same as the length of
  192. ' rgstrArgNames.
  193. '
  194. DIM rgstrArgValues(14)
  195. '-----------------------------------------------------------------
  196. ' Extract an argument name from an argument string.
  197. '
  198. ' "/STATE=DISABLE" -> "STATE"
  199. '
  200. PRIVATE FUNCTION ArgNameFromArg(strArg)
  201. s = strArg
  202. iSlash = InStr(s, "/")
  203. IF 0 <> iSlash THEN
  204. s = MID(s, iSlash+1)
  205. END IF
  206. iEqual = INSTR(s, "=")
  207. IF 0 <> iEqual THEN
  208. s = LEFT(s, iEqual-1)
  209. END IF
  210. ArgNameFromArg = UCASE(s)
  211. END FUNCTION
  212. '-----------------------------------------------------------------
  213. ' Extract an argument value from an argument string.
  214. '
  215. ' "/STATE=DISABLE" -> "DISABLE"
  216. '
  217. PRIVATE FUNCTION ArgValueFromArg(strArg)
  218. iEqual = INSTR(strArg, "=")
  219. ArgValueFromArg = MID(strArg, iEqual+1)
  220. END FUNCTION
  221. '-----------------------------------------------------------------
  222. ' Determine the index into the global arrays for
  223. ' a given argument string.
  224. '
  225. ' "STATE" -> 1
  226. ' "DEFLIMIT" -> 3
  227. '
  228. PRIVATE FUNCTION ArgNameToIndex(strArgName)
  229. ArgNameToIndex = -1
  230. n = UBOUND(rgstrArgNames) - LBOUND(rgstrArgNames)
  231. FOR i = 0 TO n
  232. IF strArgName = rgstrArgNames(i) THEN
  233. ArgNameToIndex = i
  234. EXIT FUNCTION
  235. END IF
  236. NEXT
  237. END FUNCTION
  238. '-----------------------------------------------------------------
  239. ' Convert a state name into a state code for passing to
  240. ' the QuotaState property.
  241. '
  242. ' "DISABLE" -> 0
  243. '
  244. PRIVATE FUNCTION StateFromStateName(strName)
  245. StateFromStateName = -1
  246. n = UBOUND(rgstrStateNames) - LBOUND(rgstrStateNames)
  247. FOR i = 0 TO n-1
  248. IF rgstrStateNames(i) = UCASE(strName) THEN
  249. StateFromStateName = i
  250. EXIT FUNCTION
  251. END IF
  252. NEXT
  253. END FUNCTION
  254. '-----------------------------------------------------------------
  255. ' Convert a name resolution name into a code for passing to
  256. ' the UserNameResolution property.
  257. '
  258. ' "SYNC" -> 1
  259. '
  260. PRIVATE FUNCTION NameResTypeFromTypeName(strName)
  261. NameResTypeFromTypeName = -1
  262. n = UBOUND(rgstrNameRes) - LBOUND(rgstrNameRes)
  263. FOR i = 0 TO n-1
  264. IF rgstrNameRes(i) = UCASE(strName) THEN
  265. NameResTypeFromTypeName = i
  266. EXIT FUNCTION
  267. END IF
  268. NEXT
  269. END FUNCTION
  270. '-----------------------------------------------------------------
  271. ' Process the arguments on the cmd line, storing the argument
  272. ' values in the appropriate slot in rgstrArgValues[]
  273. '
  274. PRIVATE FUNCTION ProcessArgs
  275. SET args = Wscript.Arguments
  276. n = args.COUNT
  277. FOR i = 0 TO n-1
  278. name = ArgNameFromArg(args(i))
  279. iArg = ArgNameToIndex(name)
  280. IF -1 <> iArg THEN
  281. rgstrArgValues(iArg) = UCASE(ArgValueFromArg(args(i)))
  282. IF iArg = iArgShow THEN
  283. rgstrArgValues(iArg) = "SHOW"
  284. END IF
  285. ELSE
  286. Wscript.Echo "Invalid option specified [", name, "]"
  287. END IF
  288. NEXT
  289. ProcessArgs = n
  290. END FUNCTION
  291. '-----------------------------------------------------------------
  292. ' Determine if a given argument was present on the cmd line.
  293. '
  294. PRIVATE FUNCTION ArgIsPresent(iArg)
  295. ArgIsPresent = (0 < LEN(rgstrArgValues(iArg)))
  296. END FUNCTION
  297. '-----------------------------------------------------------------
  298. ' Display quota information specific to a volume.
  299. '
  300. PRIVATE SUB ShowVolumeInfo(objDQC)
  301. Wscript.Echo ""
  302. Wscript.Echo "Volume............: ", rgstrArgValues(iArgVolume)
  303. Wscript.Echo "State.............: ", rgstrStateNames(objDQC.QuotaState)
  304. Wscript.Echo "Incomplete........: ", CSTR(objDQC.QuotaFileIncomplete)
  305. Wscript.Echo "Rebuilding........: ", CSTR(objDQC.QuotaFileRebuilding)
  306. Wscript.Echo "Name resolution...: ", rgstrNameRes(objDQC.UserNameResolution)
  307. Wscript.Echo "Default Limit.....: ", objDQC.DefaultQuotaLimitText, "(", objDQC.DefaultQuotaLimit, "bytes)"
  308. Wscript.Echo "Default Warning...: ", objDQC.DefaultQuotaThresholdText, "(", objDQC.DefaultQuotaThreshold, "bytes)"
  309. Wscript.Echo "Log limit.........: ", CSTR(objDQC.LogQuotaLimit)
  310. Wscript.Echo "Log Warning.......: ", CSTR(objDQC.LogQuotaThreshold)
  311. Wscript.Echo ""
  312. END SUB
  313. '-----------------------------------------------------------------
  314. ' Display quota information specific to a single user.
  315. '
  316. PRIVATE SUB ShowUserInfo(objUser)
  317. Wscript.Echo "Name..............: ", objUser.LogonName
  318. Wscript.Echo "Limit.............: ", objUser.QuotaLimitText, "(",objUser.QuotaLimit, "bytes)"
  319. Wscript.Echo "Warning...........: ", objUser.QuotaThresholdText, "(",objUser.QuotaThreshold, "bytes)"
  320. Wscript.Echo ""
  321. END SUB
  322. '-----------------------------------------------------------------
  323. ' Do the work according to what argument values are in
  324. ' rgstrArgValues[].
  325. '
  326. PRIVATE SUB Main
  327. DIM objDQC
  328. DIM objUser
  329. '
  330. ' User must enter volume ID.
  331. ' If none specified, display error msg and exit.
  332. '
  333. IF NOT ArgIsPresent(iArgVolume) THEN
  334. Wscript.Echo "Must provide volume ID. (i.e. '/VOLUME=C:' )"
  335. EXIT SUB
  336. END IF
  337. '
  338. ' Create the disk quota control object.
  339. '
  340. SET objDQC = Wscript.CreateObject("Microsoft.DiskQuota.1")
  341. objDQC.Initialize rgstrArgValues(iArgVolume), 1
  342. '
  343. ' Set the quota state.
  344. '
  345. IF ArgIsPresent(iArgState) THEN
  346. iState = StateFromStateName(rgstrArgValues(iArgState))
  347. IF (-1 < iState) THEN
  348. objDQC.QuotaState = iState
  349. ELSE
  350. Wscript.Echo "Invalid quota state (" & rgstrArgValues(iArgState) & ")"
  351. END IF
  352. END IF
  353. '
  354. ' Set the name resolution type. We won't use this setting here
  355. ' but set it to verify we can.
  356. '
  357. IF ArgIsPresent(iArgNameRes) THEN
  358. iResType = NameResTypeFromTypeName(rgstrArgValues(iArgNameRes))
  359. IF (-1 < iResType) THEN
  360. objDQC.UserNameResolution = iResType
  361. ELSE
  362. Wscript.Echo "Invalid name resolution type (" & rgstrArgValues(iArgNameRes) & ")"
  363. END IF
  364. END IF
  365. '
  366. ' Set the limit and threshold.
  367. '
  368. IF ArgIsPresent(iArgDefLimit) THEN
  369. objDQC.DefaultQuotaLimit = rgstrArgValues(iArgDefLimit)
  370. END IF
  371. IF ArgIsPresent(iArgDefWarning) THEN
  372. objDQC.DefaultQuotaThreshold = rgstrArgValues(iArgDefWarning)
  373. END IF
  374. '
  375. ' Set the logging flags.
  376. '
  377. IF ArgIsPresent(iArgLogLimit) THEN
  378. s = rgstrArgValues(iArgLogLimit)
  379. IF UCASE(s) = "NO" THEN
  380. objDQC.LogQuotaLimit = 0
  381. ELSE
  382. objDQC.LogQuotaLimit = 1
  383. END IF
  384. END IF
  385. IF ArgIsPresent(iArgLogWarning) THEN
  386. s = rgstrArgValues(iArgLogWarning)
  387. IF UCASE(s) = "NO" THEN
  388. objDQC.LogQuotaThreshold = 0
  389. ELSE
  390. objDQC.LogQuotaThreshold = 1
  391. END IF
  392. END IF
  393. '
  394. ' Show volume information.
  395. '
  396. IF ArgIsPresent(iArgShow) THEN
  397. ShowVolumeInfo(objDQC)
  398. END IF
  399. '
  400. ' Show user information.
  401. '
  402. IF ArgIsPresent(iArgShowUser) THEN
  403. IF rgstrArgValues(iArgShowUser) = "*" THEN
  404. '
  405. ' Enumerate all users on the volume.
  406. '
  407. FOR EACH objUser in objDQC
  408. ShowUserInfo(objUser)
  409. NEXT
  410. ELSE
  411. '
  412. ' Find and show info for just one user.
  413. '
  414. SET objUser = objDQC.FindUser(rgstrArgValues(iArgShowUser))
  415. IF TYPENAME(objUser) <> "" THEN
  416. ShowUserInfo(objUser)
  417. END IF
  418. END IF
  419. SET objUser = NOTHING
  420. END IF
  421. '
  422. ' Delete user.
  423. '
  424. IF ArgIsPresent(iArgDelUser) THEN
  425. SET objUser = objDQC.FindUser(rgstrArgValues(iArgDelUser))
  426. IF TYPENAME(objUser) <> "" THEN
  427. objDQC.DeleteUser(objUser)
  428. Wscript.Echo "Quota record for ", rgstrArgValues(iArgDelUser), "deleted from volume."
  429. SET objUser = NOTHING
  430. END IF
  431. END IF
  432. '
  433. ' Set user warning level and/or limit.
  434. '
  435. IF ArgIsPresent(iArgLimit) OR ArgIsPresent(iArgWarning) THEN
  436. IF NOT ArgIsPresent(iArgUser) THEN
  437. Wscript.Echo "Must provide user logon name. (i.e. '/USER=REDMOND\mmouse' )"
  438. EXIT SUB
  439. END IF
  440. SET objUser = objDQC.FindUser(rgstrArgValues(iArgUser))
  441. IF TYPENAME(objUser) <> "" THEN
  442. IF ArgIsPresent(iArgLimit) THEN
  443. objUser.QuotaLimit = rgstrArgValues(iArgLimit)
  444. END IF
  445. IF ArgIsPresent(iArgWarning) THEN
  446. objUser.QuotaThreshold = rgstrArgValues(iArgWarning)
  447. END IF
  448. END IF
  449. SET objUser = NOTHING
  450. END IF
  451. '
  452. ' Add new user quota record.
  453. '
  454. IF ArgIsPresent(iArgAddUser) THEN
  455. SET objUser = objDQC.AddUser(rgstrArgValues(iArgAddUser))
  456. IF TYPENAME(objUser) <> "" THEN
  457. Wscript.Echo "Quota record for ", rgstrArgValues(iArgAddUser), "added to volume."
  458. END IF
  459. SET objUser = NOTHING
  460. END IF
  461. SET objDQC = NOTHING
  462. END SUB
  463. '-----------------------------------------------------------------
  464. ' MAIN
  465. '
  466. ProcessArgs ' Parse all cmd line args.
  467. Main ' Do the work.