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.

389 lines
7.7 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1997, Microsoft Corp. All rights reserved.
  4. //
  5. // FILE
  6. //
  7. // iasutil.cpp
  8. //
  9. // SYNOPSIS
  10. //
  11. // This file implements assorted utility functions, etc.
  12. //
  13. // MODIFICATION HISTORY
  14. //
  15. // 11/14/1997 Original version.
  16. // 08/11/1998 Major overhaul and consolidation of utility functions.
  17. //
  18. ///////////////////////////////////////////////////////////////////////////////
  19. #include <ias.h>
  20. #include <iasapi.h>
  21. #include <iasutil.h>
  22. ///////////////////////////////////////////////////////////////////////////////
  23. //
  24. // String functions.
  25. //
  26. ///////////////////////////////////////////////////////////////////////////////
  27. // Duplicates a WSTR using new[].
  28. PWSTR
  29. WINAPI
  30. ias_wcsdup(PCWSTR str)
  31. {
  32. LPWSTR sz = NULL;
  33. if (str)
  34. {
  35. size_t len = wcslen(str) + 1;
  36. if (sz = new (std::nothrow) WCHAR[len])
  37. {
  38. memcpy(sz, str, len * sizeof(WCHAR));
  39. }
  40. }
  41. return sz;
  42. }
  43. // Duplicates a STR using CoTaskMemAlloc.
  44. PSTR
  45. WINAPI
  46. com_strdup(PCSTR str)
  47. {
  48. LPSTR sz = NULL;
  49. if (str)
  50. {
  51. size_t size = sizeof(CHAR) * (strlen(str) + 1);
  52. if (sz = (LPSTR)CoTaskMemAlloc(size))
  53. {
  54. memcpy(sz, str, size);
  55. }
  56. }
  57. return sz;
  58. }
  59. // Duplicates a WSTR using CoTaskMemAlloc.
  60. PWSTR
  61. WINAPI
  62. com_wcsdup(PCWSTR str)
  63. {
  64. LPWSTR sz = NULL;
  65. if (str)
  66. {
  67. size_t size = sizeof(WCHAR) * (wcslen(str) + 1);
  68. if (sz = (LPWSTR)CoTaskMemAlloc(size))
  69. {
  70. memcpy(sz, str, size);
  71. }
  72. }
  73. return sz;
  74. }
  75. // Compares two WSTR's allowing for null pointers.
  76. INT
  77. WINAPI
  78. ias_wcscmp(PCWSTR str1, PCWSTR str2)
  79. {
  80. if (str1 != NULL && str2 != NULL) return wcscmp(str1, str2);
  81. return str1 == str2 ? 0 : (str1 > str2 ? 1 : -1);
  82. }
  83. // Concatenate a null-terminated list of strings.
  84. LPWSTR
  85. WINAPIV
  86. ias_makewcs(LPCWSTR str1, ...)
  87. {
  88. size_t len = 0;
  89. //////////
  90. // Iterate through the arguments and calculate how much space we need.
  91. //////////
  92. va_list marker;
  93. va_start(marker, str1);
  94. LPCWSTR sz = str1;
  95. while (sz)
  96. {
  97. len += wcslen(sz);
  98. sz = va_arg(marker, LPCWSTR);
  99. }
  100. va_end(marker);
  101. // Add room for the null-terminator.
  102. ++len;
  103. //////////
  104. // Allocate memory to hold the concatentated string.
  105. //////////
  106. LPWSTR rv = new (std::nothrow) WCHAR[len];
  107. if (!rv) return NULL;
  108. // Initialize the string so wcscat will work.
  109. *rv = L'\0';
  110. //////////
  111. // Concatenate the strings.
  112. //////////
  113. va_start(marker, str1);
  114. sz = str1;
  115. while (sz)
  116. {
  117. wcscat(rv, sz);
  118. sz = va_arg(marker, LPCWSTR);
  119. }
  120. va_end(marker);
  121. return rv;
  122. }
  123. ///////////////////////////////////////////////////////////////////////////////
  124. //
  125. // Functions to move integers to and from a buffer.
  126. //
  127. ///////////////////////////////////////////////////////////////////////////////
  128. VOID
  129. WINAPI
  130. IASInsertDWORD(
  131. PBYTE pBuffer,
  132. DWORD dwValue
  133. )
  134. {
  135. *pBuffer++ = (BYTE)((dwValue >> 24) & 0xFF);
  136. *pBuffer++ = (BYTE)((dwValue >> 16) & 0xFF);
  137. *pBuffer++ = (BYTE)((dwValue >> 8) & 0xFF);
  138. *pBuffer = (BYTE)((dwValue ) & 0xFF);
  139. }
  140. DWORD
  141. WINAPI
  142. IASExtractDWORD(
  143. CONST BYTE *pBuffer
  144. )
  145. {
  146. return (DWORD)(pBuffer[0] << 24) | (DWORD)(pBuffer[1] << 16) |
  147. (DWORD)(pBuffer[2] << 8) | (DWORD)(pBuffer[3] );
  148. }
  149. VOID
  150. WINAPI
  151. IASInsertWORD(
  152. PBYTE pBuffer,
  153. WORD wValue
  154. )
  155. {
  156. *pBuffer++ = (BYTE)((wValue >> 8) & 0xFF);
  157. *pBuffer = (BYTE)((wValue ) & 0xFF);
  158. }
  159. WORD
  160. WINAPI
  161. IASExtractWORD(
  162. CONST BYTE *pBuffer
  163. )
  164. {
  165. return (WORD)(pBuffer[0] << 8) | (WORD)(pBuffer[1]);
  166. }
  167. ///////////////////////////////////////////////////////////////////////////////
  168. //
  169. // Extensions to _com_error to handle Win32 errors.
  170. //
  171. ///////////////////////////////////////////////////////////////////////////////
  172. void __stdcall _w32_issue_error(DWORD errorCode) throw (_w32_error)
  173. {
  174. throw _w32_error(errorCode);
  175. }
  176. namespace
  177. {
  178. // Get the path to a database on the local computer.
  179. DWORD GetDatabasePath(
  180. const wchar_t* fileName,
  181. wchar_t* buffer,
  182. DWORD* size
  183. ) throw ()
  184. {
  185. // Value where the path to the IAS directory is stored.
  186. static const wchar_t productDirValue[] = L"ProductDir";
  187. if ((fileName == 0) || (buffer == 0) || (size == 0))
  188. {
  189. return ERROR_INVALID_PARAMETER;
  190. }
  191. // Initialize the out parameter.
  192. DWORD inSize = *size;
  193. *size = 0;
  194. // Open the registry key.
  195. LONG result;
  196. HKEY hKey;
  197. result = RegOpenKeyExW(
  198. HKEY_LOCAL_MACHINE,
  199. IAS_POLICY_KEY,
  200. 0,
  201. KEY_READ,
  202. &hKey
  203. );
  204. if (result != NO_ERROR)
  205. {
  206. return result;
  207. }
  208. // Read the ProductDir value.
  209. DWORD dwType;
  210. DWORD cbData = inSize * sizeof(wchar_t);
  211. result = RegQueryValueExW(
  212. hKey,
  213. productDirValue,
  214. 0,
  215. &dwType,
  216. reinterpret_cast<BYTE*>(buffer),
  217. &cbData
  218. );
  219. // We're done with the registry key.
  220. RegCloseKey(hKey);
  221. // Compute the length of the full path in characters.
  222. DWORD outSize = (cbData / sizeof(WCHAR)) + wcslen(fileName);
  223. if (result != NO_ERROR)
  224. {
  225. // If we overflowed, return the needed size.
  226. if (result == ERROR_MORE_DATA)
  227. {
  228. *size = outSize;
  229. }
  230. return result;
  231. }
  232. // The registry value must contain a string.
  233. if (dwType != REG_SZ)
  234. {
  235. return REGDB_E_INVALIDVALUE;
  236. }
  237. // Do we have enough room to append the filename.
  238. if (outSize <= inSize)
  239. {
  240. wcscat(buffer, fileName);
  241. }
  242. else
  243. {
  244. result = ERROR_MORE_DATA;
  245. }
  246. // Return the size (whether actual or needed).
  247. *size = outSize;
  248. return result;
  249. }
  250. }
  251. DWORD
  252. WINAPI
  253. IASGetConfigPath(
  254. OUT PWSTR buffer,
  255. IN OUT PDWORD size
  256. )
  257. {
  258. return GetDatabasePath(L"\\ias.mdb", buffer, size);
  259. }
  260. DWORD
  261. WINAPI
  262. IASGetDictionaryPath(
  263. OUT PWSTR buffer,
  264. IN OUT PDWORD size
  265. )
  266. {
  267. return GetDatabasePath(L"\\dnary.mdb", buffer, size);
  268. }
  269. DWORD
  270. WINAPI
  271. IASGetProductLimitsForType(
  272. IN IAS_LICENSE_TYPE type,
  273. OUT IAS_PRODUCT_LIMITS* limits
  274. )
  275. {
  276. static const IAS_PRODUCT_LIMITS workstationLimits =
  277. {
  278. 0,
  279. FALSE,
  280. 0
  281. };
  282. static const IAS_PRODUCT_LIMITS standardServerLimits =
  283. {
  284. 50,
  285. FALSE,
  286. 2
  287. };
  288. static const IAS_PRODUCT_LIMITS unlimitedServerLimits =
  289. {
  290. IAS_NO_LIMIT,
  291. TRUE,
  292. IAS_NO_LIMIT
  293. };
  294. if (limits == 0)
  295. {
  296. return ERROR_INVALID_PARAMETER;
  297. }
  298. switch (type)
  299. {
  300. case IASLicenseTypeProfessional:
  301. case IASLicenseTypePersonal:
  302. {
  303. *limits = workstationLimits;
  304. break;
  305. }
  306. case IASLicenseTypeStandardServer:
  307. case IASLicenseTypeWebBlade:
  308. case IASLicenseTypeSmallBusinessServer:
  309. {
  310. *limits = standardServerLimits;
  311. break;
  312. }
  313. case IASLicenseTypeDownlevel:
  314. case IASLicenseTypeEnterpriseServer:
  315. case IASLicenseTypeDataCenter:
  316. {
  317. *limits = unlimitedServerLimits;
  318. break;
  319. }
  320. default:
  321. {
  322. return ERROR_INVALID_PARAMETER;
  323. }
  324. }
  325. return NO_ERROR;
  326. }