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.

361 lines
10 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. cliutils.cpp
  5. Abstract:
  6. Implements internal CLI unit utilities
  7. Author:
  8. Ran Kalach [rankala] 8-March-2000
  9. Revision History:
  10. --*/
  11. #include "stdafx.h"
  12. #include "HsmConn.h"
  13. static GUID g_nullGuid = GUID_NULL;
  14. HRESULT
  15. ValidateLimitsArg(
  16. IN DWORD dwArgValue,
  17. IN DWORD dwArgId,
  18. IN DWORD dwMinLimit,
  19. IN DWORD dwMaxLimit
  20. )
  21. /*++
  22. Routine Description:
  23. Validates the argument and print error message if necessary
  24. Arguments:
  25. dwArgValue - The value to check
  26. dwArgId - Id for resource string of the arg
  27. dwMinLimit - The Min limit to compare, INVALID_DWORD_ARG for Max compare
  28. dwMaxLimit - The Max limit to compare, INVALID_DWORD_ARG for Min compare
  29. Return Value:
  30. S_OK - The argument is OK (or not in use)
  31. E_INVALIDARG - The argument is not in the limit range
  32. --*/
  33. {
  34. HRESULT hr = S_OK;
  35. WsbTraceIn(OLESTR("ValidateOneLimitArg"), OLESTR(""));
  36. try {
  37. CWsbStringPtr param;
  38. WCHAR strLongParm1[30];
  39. WCHAR strLongParm2[30];
  40. WCHAR strLongParm3[30];
  41. if (INVALID_DWORD_ARG != dwArgValue) {
  42. if ((INVALID_DWORD_ARG != dwMinLimit) && (INVALID_DWORD_ARG != dwMaxLimit)) {
  43. // Min-Max test
  44. if ((dwArgValue < dwMinLimit) || (dwArgValue > dwMaxLimit)) {
  45. WsbAffirmHr(param.LoadFromRsc(g_hInstance, dwArgId));
  46. swprintf(strLongParm1, OLESTR("%lu"), dwArgValue);
  47. swprintf(strLongParm2, OLESTR("%lu"), dwMinLimit);
  48. swprintf(strLongParm3, OLESTR("%lu"), dwMaxLimit);
  49. WsbTraceAndPrint(CLI_MESSAGE_INVALID_ARG3, (WCHAR *)param,
  50. strLongParm1, strLongParm2, strLongParm3, NULL);
  51. WsbThrow(E_INVALIDARG);
  52. }
  53. } else if (INVALID_DWORD_ARG != dwMinLimit) {
  54. // Min test
  55. if (dwArgValue < dwMinLimit) {
  56. WsbAffirmHr(param.LoadFromRsc(g_hInstance, dwArgId));
  57. swprintf(strLongParm1, OLESTR("%lu"), dwArgValue);
  58. swprintf(strLongParm2, OLESTR("%lu"), dwMinLimit);
  59. WsbTraceAndPrint(CLI_MESSAGE_INVALID_ARG1, (WCHAR *)param,
  60. strLongParm1, strLongParm2, NULL);
  61. WsbThrow(E_INVALIDARG);
  62. }
  63. } else if (INVALID_DWORD_ARG != dwMaxLimit) {
  64. // Max test
  65. if (dwArgValue > dwMaxLimit) {
  66. WsbAffirmHr(param.LoadFromRsc(g_hInstance, dwArgId));
  67. swprintf(strLongParm1, OLESTR("%lu"), dwArgValue);
  68. swprintf(strLongParm2, OLESTR("%lu"), dwMaxLimit);
  69. WsbTraceAndPrint(CLI_MESSAGE_INVALID_ARG2, (WCHAR *)param,
  70. strLongParm1, strLongParm2, NULL);
  71. WsbThrow(E_INVALIDARG);
  72. }
  73. }
  74. }
  75. } WsbCatch(hr);
  76. WsbTraceOut(OLESTR("ValidateOneLimitArg"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  77. return (hr);
  78. }
  79. HRESULT SaveServersPersistData(
  80. void
  81. )
  82. /*++
  83. Routine Description:
  84. Save persistent data for HSM servers
  85. Arguments:
  86. None
  87. Return Value:
  88. S_OK - The persistent data is saved successfully for all HSM servers
  89. --*/
  90. {
  91. HRESULT hr = S_OK;
  92. WsbTraceIn(OLESTR("SaveServersPersistData"), OLESTR(""));
  93. try {
  94. CComPtr<IHsmServer> pHsm;
  95. CComPtr<IFsaServer> pFsa;
  96. CComPtr<IWsbServer> pWsbServer;
  97. // Engine
  98. WsbAffirmHr(HsmConnectFromId(HSMCONN_TYPE_HSM, g_nullGuid, IID_IHsmServer, (void**)&pHsm));
  99. WsbAffirmHr(pHsm->SavePersistData());
  100. // Fsa
  101. WsbAffirmHr(HsmConnectFromId(HSMCONN_TYPE_FSA, g_nullGuid, IID_IFsaServer, (void**)&pFsa));
  102. WsbAffirmHr(pFsa->QueryInterface(IID_IWsbServer, (void**)&pWsbServer));
  103. WsbAffirmHr(pWsbServer->SaveAll());
  104. } WsbCatch(hr);
  105. WsbTraceOut(OLESTR("SaveServersPersistData"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  106. return (hr);
  107. }
  108. /* converts numbers into sort formats
  109. * 532 -> 523 bytes
  110. * 1340 -> 1.3KB
  111. * 23506 -> 23.5KB
  112. * -> 2.4MB
  113. * -> 5.2GB
  114. */
  115. // NOTE: This code is cloned from MS source /shell/shelldll/util.c (and from \hsm\gui\inc\rsutil.cpp)
  116. #define HIDWORD(_qw) (DWORD)((_qw)>>32)
  117. #define LODWORD(_qw) (DWORD)(_qw)
  118. #define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
  119. const int pwOrders[] = {IDS_BYTES, IDS_ORDERKB, IDS_ORDERMB,
  120. IDS_ORDERGB, IDS_ORDERTB, IDS_ORDERPB, IDS_ORDEREB};
  121. HRESULT ShortSizeFormat64(__int64 dw64, LPTSTR szBuf)
  122. {
  123. int i;
  124. UINT wInt, wLen, wDec;
  125. TCHAR szTemp[10], szOrder[20], szFormat[5];
  126. if (dw64 < 1000) {
  127. wsprintf(szTemp, TEXT("%d"), LODWORD(dw64));
  128. i = 0;
  129. goto AddOrder;
  130. }
  131. for (i = 1; i<ARRAYSIZE(pwOrders)-1 && dw64 >= 1000L * 1024L; dw64 >>= 10, i++);
  132. /* do nothing */
  133. wInt = LODWORD(dw64 >> 10);
  134. AddCommas(wInt, szTemp, 10);
  135. wLen = lstrlen(szTemp);
  136. if (wLen < 3)
  137. {
  138. wDec = LODWORD(dw64 - (__int64)wInt * 1024L) * 1000 / 1024;
  139. // At this point, wDec should be between 0 and 1000
  140. // we want get the top one (or two) digits.
  141. wDec /= 10;
  142. if (wLen == 2)
  143. wDec /= 10;
  144. // Note that we need to set the format before getting the
  145. // intl char.
  146. lstrcpy(szFormat, TEXT("%02d"));
  147. szFormat[2] = (TCHAR)( TEXT('0') + 3 - wLen );
  148. GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL,
  149. szTemp+wLen, ARRAYSIZE(szTemp)-wLen);
  150. wLen = lstrlen(szTemp);
  151. wLen += wsprintf(szTemp+wLen, szFormat, wDec);
  152. }
  153. AddOrder:
  154. LoadString(g_hInstance, pwOrders[i], szOrder, ARRAYSIZE(szOrder));
  155. wsprintf(szBuf, szOrder, (LPTSTR)szTemp);
  156. return S_OK;
  157. }
  158. /*
  159. * takes a DWORD add commas etc to it and puts the result in the buffer
  160. */
  161. // NOTE: This code is cloned from MS source /shell/shelldll/util.c (and from \hsm\gui\inc\rsutil.cpp)
  162. LPTSTR AddCommas(DWORD dw, LPTSTR pszResult, int nResLen)
  163. {
  164. TCHAR szTemp[20]; // more than enough for a DWORD
  165. TCHAR szSep[5];
  166. NUMBERFMT nfmt;
  167. nfmt.NumDigits=0;
  168. nfmt.LeadingZero=0;
  169. GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SGROUPING, szSep, ARRAYSIZE(szSep));
  170. nfmt.Grouping = _tcstol(szSep, NULL, 10);
  171. GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, szSep, ARRAYSIZE(szSep));
  172. nfmt.lpDecimalSep = nfmt.lpThousandSep = szSep;
  173. nfmt.NegativeOrder= 0;
  174. wsprintf(szTemp, TEXT("%lu"), dw);
  175. if (GetNumberFormat(LOCALE_USER_DEFAULT, 0, szTemp, &nfmt, pszResult, nResLen) == 0)
  176. lstrcpy(pszResult, szTemp);
  177. return pszResult;
  178. }
  179. HRESULT
  180. FormatFileTime(
  181. IN FILETIME ft,
  182. OUT WCHAR **ppTimeString
  183. )
  184. /*++
  185. Routine Description:
  186. Fotmat a time given in GMT (system) time to a string
  187. Arguments:
  188. ft - The input time in FILETIME format
  189. ppTimeString - Output buffer. Caller is expected to free using WsbFree in case of success
  190. Return Value:
  191. S_OK - If the time is formatted successfully
  192. --*/
  193. {
  194. HRESULT hr = S_OK;
  195. WCHAR* pTime = NULL;
  196. WsbTraceIn(OLESTR("FormatFileTime"), OLESTR(""));
  197. try {
  198. FILETIME ftLocal;
  199. SYSTEMTIME stLocal;
  200. WsbAffirm(0 != ppTimeString, E_INVALIDARG);
  201. *ppTimeString = NULL;
  202. // Translate to local time in SYSTEMTIME format
  203. WsbAffirmStatus(FileTimeToLocalFileTime(&ft, &ftLocal));
  204. WsbAffirmStatus(FileTimeToSystemTime(&ftLocal, &stLocal));
  205. // Find required buffer
  206. int nChars1 = GetDateFormat(LOCALE_SYSTEM_DEFAULT, 0, &stLocal, NULL, NULL, 0);
  207. int nChars2 = GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, &stLocal, NULL, NULL, 0);
  208. pTime = (WCHAR *)WsbAlloc((nChars1+nChars2+1) * sizeof(WCHAR));
  209. WsbAffirm(0 != pTime, E_OUTOFMEMORY);
  210. // Create time string
  211. WsbAffirmStatus(GetDateFormat(LOCALE_SYSTEM_DEFAULT, 0, &stLocal, NULL, pTime, nChars1));
  212. pTime[nChars1-1] = L' ';
  213. WsbAffirmStatus(GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, &stLocal, NULL, &(pTime[nChars1]), nChars2));
  214. *ppTimeString = pTime;
  215. } WsbCatchAndDo(hr,
  216. // Free in case of an error
  217. if (pTime) {
  218. WsbFree(pTime);
  219. pTime = NULL;
  220. }
  221. );
  222. WsbTraceOut(OLESTR("FormatFileTime"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  223. return (hr);
  224. }
  225. HRESULT
  226. CliGetVolumeDisplayName(
  227. IN IUnknown *pResourceUnknown,
  228. OUT WCHAR **ppDisplayName
  229. )
  230. /*++
  231. Routine Description:
  232. Produce a display name for a volume
  233. Arguments:
  234. pResourceUnknown - The input Fsa Resource object
  235. ppDisplayName - Output buffer. Caller is expected to free using WsbFree in case of success
  236. Return Value:
  237. S_OK - If the name is retrieved successfully
  238. --*/
  239. {
  240. HRESULT hr = S_OK;
  241. WsbTraceIn(OLESTR("CliGetVolumeDisplayName"), OLESTR(""));
  242. try {
  243. CComPtr<IFsaResource> pResource;
  244. // Check and initialize parameters
  245. WsbAffirm(0 != ppDisplayName, E_INVALIDARG);
  246. *ppDisplayName = NULL;
  247. WsbAffirmHr(pResourceUnknown->QueryInterface(IID_IFsaResource, (void **)&pResource));
  248. // Prefer user friendly name
  249. // If not exists, use label
  250. // If no label, use constant
  251. CWsbStringPtr userName;
  252. WsbAffirmHr(pResource->GetUserFriendlyName(&userName, 0));
  253. if (userName.IsEqual(L"")) {
  254. userName.Free();
  255. WsbAffirmHr(pResource->GetName(&userName, 0));
  256. if (userName.IsEqual(L"")) {
  257. userName.Free();
  258. WsbAffirmHr(userName.LoadFromRsc(g_hInstance, IDS_UNLABELED_VOLUME));
  259. }
  260. }
  261. *ppDisplayName = (WCHAR *)WsbAlloc((wcslen(userName) + 1) * sizeof(WCHAR));
  262. WsbAffirm(0 != *ppDisplayName, E_OUTOFMEMORY);
  263. wcscpy(*ppDisplayName, userName);
  264. } WsbCatch(hr);
  265. WsbTraceOut(OLESTR("CliGetVolumeDisplayName"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  266. return (hr);
  267. }