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.

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