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.

492 lines
10 KiB

  1. #include "util.h"
  2. WCHAR g_szwIds[MAX_PATH + 1];
  3. WCHAR g_szwSpace[MAX_PATH + 1];
  4. WCHAR *
  5. ids(LONG nIndex)
  6. {
  7. if( LoadString((HINSTANCE)g_hModule,nIndex,g_szwIds,MAX_PATH) )
  8. {
  9. g_szwIds[MAX_PATH] = L'\0';
  10. return g_szwIds;
  11. }
  12. else
  13. {
  14. return L"";
  15. }
  16. }
  17. WCHAR *
  18. Space(
  19. int nSpace
  20. )
  21. {
  22. for(int i=0; i<nSpace && i< MAX_PATH; i++)
  23. {
  24. g_szwSpace[i] = L' ';
  25. }
  26. g_szwSpace[i] = L'\0';
  27. return g_szwSpace;
  28. }
  29. WCHAR *
  30. Indent(
  31. int nIndent
  32. )
  33. {
  34. return Space(nIndent * 4);
  35. }
  36. BOOLEAN
  37. IsNumber(
  38. IN LPCTSTR pszw
  39. )
  40. {
  41. if( !pszw )
  42. {
  43. return FALSE;
  44. }
  45. for(int i=0; pszw[i]!=L'\0'; i++)
  46. {
  47. if( !isdigit(pszw[i]) )
  48. {
  49. return FALSE;
  50. }
  51. }
  52. return TRUE;
  53. }
  54. BOOLEAN
  55. IsContained(
  56. IN LPCTSTR pszwInstance,
  57. IN LPCTSTR pszwSrch
  58. )
  59. /*++
  60. Routine Description
  61. This method compares two strings and determines if the strings resemble each
  62. other. If the strings are identical, then they resemble each other.
  63. If the search string (pszwSrch) starts or ends with a '*', then the method
  64. checks if the search string is contained inside of the instance string (pszwInstance).
  65. i.e. pszwInstance = 3Com 3C918 Integrated Fast Ethernet Controller (3C905B-TX Compatible)
  66. pszwSrch = com* | *com
  67. then pszwSrch resembles pszwInstance. The string compare is not case sensative.
  68. Arguments
  69. pszwInstance The instance string
  70. pszwSrch The search string
  71. Return Value
  72. TRUE if the strings resemble each other
  73. else FALSE
  74. --*/
  75. {
  76. LPCTSTR pszw = NULL;
  77. int nLen;
  78. if( !pszwSrch || !pszwInstance || lstrcmpi(pszwSrch,L"*")==0 )
  79. {
  80. // The strings are empty, so they match.
  81. //
  82. return TRUE;
  83. }
  84. if( pszwSrch[0] == L'*' )
  85. {
  86. // The search string starts with a '*', check if the search
  87. // string is contained in the instance string
  88. //
  89. pszw = &pszwSrch[1];
  90. if( wcsstri(pszwInstance,pszw) )
  91. {
  92. // Search string is contain within the instance string
  93. //
  94. return TRUE;
  95. }
  96. }
  97. nLen = lstrlen(pszwSrch);
  98. if( nLen > 1 && pszwSrch[nLen -1] == L'*' )
  99. {
  100. // The search string ends with a '*'. check if the search
  101. // string is contained in the instance string
  102. //
  103. if( wcsstri(pszwInstance,pszwSrch,nLen-1) )
  104. {
  105. // Search string is contain within the instance string
  106. //
  107. return TRUE;
  108. }
  109. }
  110. if( lstrcmpi(pszwInstance,pszwSrch) == 0 )
  111. {
  112. // No '*'. Check if the strings are the same
  113. //
  114. return TRUE;
  115. }
  116. // Strings do not resemble each other
  117. //
  118. return FALSE;
  119. }
  120. void
  121. ToLowerStr(
  122. WCHAR *pszwText
  123. )
  124. {
  125. while( pszwText && *pszwText )
  126. {
  127. *pszwText = towlower(*pszwText);
  128. pszwText++;
  129. }
  130. }
  131. BOOLEAN
  132. wcsstri(
  133. IN LPCTSTR pszw,
  134. IN LPCTSTR pszwSrch,
  135. IN int nLen
  136. )
  137. {
  138. BOOLEAN bMatch = FALSE;
  139. int i=0,j=0;
  140. if( !pszw || !pszwSrch )
  141. {
  142. // Invalid pointers
  143. //
  144. return FALSE;
  145. }
  146. for(i=0; pszw[i]!=L'\0'; i++)
  147. {
  148. if( j == nLen )
  149. {
  150. return bMatch;
  151. }
  152. if( pszwSrch[j] == L'\0' )
  153. {
  154. return bMatch;
  155. }
  156. if( towlower(pszw[i]) == towlower(pszwSrch[j]) )
  157. {
  158. j++;
  159. bMatch = TRUE;
  160. }
  161. else
  162. {
  163. j=0;
  164. bMatch = FALSE;
  165. }
  166. }
  167. return FALSE;
  168. }
  169. BOOLEAN IsVariantEmpty(_variant_t &vValue)
  170. {
  171. _bstr_t bstr;
  172. if( SUCCEEDED(GetVariant(vValue,0,bstr)) )
  173. {
  174. return lstrcmp(bstr,L"") == 0;
  175. }
  176. return TRUE;
  177. }
  178. BOOLEAN MakeIPByteArray(LPCTSTR pszwIPAddress, BYTE bIPByte[])
  179. {
  180. LONG nByteValue = 0;
  181. LONG nByte = 0;
  182. for(int i=0; pszwIPAddress[i]!=0; i++)
  183. {
  184. if( pszwIPAddress[i] == L'.')
  185. {
  186. if( nByteValue > 255 )
  187. {
  188. return FALSE;
  189. }
  190. bIPByte[nByte] = nByteValue;
  191. nByteValue = 0;
  192. nByte++;
  193. }
  194. else
  195. {
  196. if( !iswdigit(pszwIPAddress[i]) )
  197. {
  198. return FALSE;
  199. }
  200. nByteValue = nByteValue * 10 + (pszwIPAddress[i] - L'0');
  201. }
  202. }
  203. bIPByte[nByte] = nByteValue;
  204. return (nByte != 3)?FALSE:TRUE;
  205. }
  206. /*
  207. BOOLEAN IsInvalidIPAddress(LPCTSTR pszwIPAddress)
  208. {
  209. BYTE bIPByte[4];
  210. if( MakeIPByteArray(pszwIPAddress,bIPByte) )
  211. {
  212. INT iZeroCount = 0;
  213. INT i255Count = 0;
  214. for(INT i=0; i<4; i++)
  215. {
  216. if( pszwIPAddress[i] == 0 )
  217. {
  218. iZeroCount++;
  219. }
  220. if( pszwIPAddress[i] == 255 )
  221. {
  222. i255Count++;
  223. }
  224. }
  225. if( i255Count == 4 || iZeroCount == 4 )
  226. {
  227. return TRUE;
  228. }
  229. }
  230. return FALSE;
  231. }
  232. */
  233. BOOLEAN
  234. IsSameSubnet(
  235. IN LPCTSTR pszwIP1,
  236. IN LPCTSTR pszwIP2,
  237. IN LPCTSTR pszwSubnetMask
  238. )
  239. /*++
  240. Routine Description
  241. This method determines if two IP address are in the same subnet.
  242. Arguments
  243. pszwIP1 IP Address one
  244. pszwIP2 IP Address two
  245. pszwSubnetMask Subnet mask
  246. Return Value
  247. TRUE if they are in the same subnet
  248. FALSE if they are not in the smae subnet
  249. --*/
  250. {
  251. BYTE bIP1[4];
  252. BYTE bIP2[4];
  253. BYTE bSubnetMask[4];
  254. int iRetVal;
  255. if( !MakeIPByteArray(pszwIP1,bIP1) )
  256. {
  257. return FALSE;
  258. }
  259. if( !MakeIPByteArray(pszwIP2,bIP2) )
  260. {
  261. return FALSE;
  262. }
  263. if( !MakeIPByteArray(pszwSubnetMask,bSubnetMask) )
  264. {
  265. return FALSE;
  266. }
  267. // Check if IP1 and IP2 are in the same subnet
  268. //
  269. for( int i = 0; i< 4; i++)
  270. {
  271. // If (IP1 & with Subnetmas) == (IP2 & with subnet) then they are in the same subnet
  272. //
  273. if( (bIP1[i] & bSubnetMask[i]) != (bIP2[i] & bSubnetMask[i]) )
  274. {
  275. // No the same subnet
  276. //
  277. return FALSE;
  278. }
  279. }
  280. // Same subnet
  281. //
  282. return TRUE;
  283. }
  284. BOOLEAN
  285. IsSameSubnet(
  286. IN _variant_t *vIPAddress,
  287. IN _variant_t *vSubnetMask,
  288. IN WCHAR *pszwIPAddress2
  289. )
  290. {
  291. DWORD i = 0;
  292. DWORD j = 0;
  293. _bstr_t bstrIP;
  294. _bstr_t bstrSubnetMask;
  295. if( !vIPAddress || !vSubnetMask || !pszwIPAddress2 )
  296. {
  297. return FALSE;
  298. }
  299. while( S_OK == GetVariant(*vIPAddress,i,bstrIP) )
  300. {
  301. j = 0;
  302. while( S_OK == GetVariant(*vSubnetMask,j,bstrSubnetMask) )
  303. {
  304. if( IsSameSubnet(bstrIP, pszwIPAddress2, bstrSubnetMask) )
  305. {
  306. return TRUE;
  307. }
  308. j++;
  309. }
  310. i++;
  311. }
  312. return FALSE;
  313. }
  314. HRESULT
  315. GetVariant(
  316. IN _variant_t &vValue,
  317. IN long nIndex,
  318. OUT _bstr_t &bstr
  319. )
  320. /*++
  321. Routine Description
  322. This method extracts nth piece of data from a variant, converts it into a bstring
  323. and returns the bstring.
  324. Arguments
  325. vValue Variant to extract data from
  326. nIndex The index into the variant array (for non-arrays nIndex always is 0)
  327. bstr Stores the variant as a bstr
  328. Return Value
  329. S_OK successfull
  330. else HRESULT
  331. --*/
  332. {
  333. HRESULT hr = S_FALSE;
  334. BYTE g[100];
  335. LPVOID pData = (LPVOID)g;
  336. WCHAR szw[MAX_PATH+1];
  337. _variant_t vTmp;
  338. if( nIndex >= 25 )
  339. {
  340. // The array is to big. We are cutting it short
  341. return E_INVALIDARG;
  342. }
  343. if( (vValue.vt & VT_ARRAY) )
  344. {
  345. // The variant contains an array. get the nIndex element from the array
  346. //
  347. hr = SafeArrayGetElement(vValue.parray,&nIndex,pData);
  348. if( S_OK == hr )
  349. {
  350. // Convert the extracted data into a string
  351. //
  352. switch( vValue.vt & ~VT_ARRAY )
  353. {
  354. case VT_BSTR:
  355. bstr = (BSTR)*((BSTR *)pData);
  356. return S_OK;
  357. case VT_I2:
  358. bstr = (short)*((short *)pData);
  359. return S_OK;
  360. case VT_I4:
  361. bstr = (long)*((LONG *)pData);
  362. return S_OK;
  363. case VT_UI1:
  364. bstr = (BYTE)*((BYTE *)pData);
  365. return S_OK;
  366. case VT_NULL:
  367. return S_FALSE;
  368. case VT_EMPTY:
  369. return S_FALSE;
  370. case VT_BOOL:
  371. {
  372. if( (VARIANT_BOOL *)pData )
  373. {
  374. bstr = ids(IDS_TRUE);
  375. }
  376. else
  377. {
  378. bstr = ids(IDS_FALSE);
  379. }
  380. }
  381. default:
  382. bstr = L"";
  383. return S_OK;
  384. }
  385. }
  386. }
  387. else
  388. {
  389. if( nIndex == 0)
  390. {
  391. // The variant is not an array. In this case nIndex always needs to be 0
  392. //
  393. if( vValue.vt == VT_NULL || vValue.vt == VT_EMPTY)
  394. {
  395. // The variant is empty
  396. //
  397. bstr = L"";
  398. return S_FALSE;
  399. }
  400. else if( (vValue.vt == VT_EMPTY) || (vValue.vt == VT_BSTR && lstrlen(vValue.bstrVal) == 0) )
  401. {
  402. // The variant is empty
  403. //
  404. bstr = L"";
  405. return S_FALSE;
  406. }
  407. else if( vValue.vt == VT_BOOL )
  408. {
  409. if( vValue.boolVal )
  410. {
  411. bstr = ids(IDS_TRUE);
  412. }
  413. else
  414. {
  415. bstr = ids(IDS_FALSE);
  416. }
  417. }
  418. else
  419. {
  420. // The variant contains valid data. Convert the data into a bstring.
  421. //
  422. vTmp = vValue;
  423. vTmp.ChangeType(VT_BSTR);
  424. bstr = vTmp.bstrVal;
  425. }
  426. return S_OK;
  427. }
  428. }
  429. return E_INVALIDARG;
  430. }