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.

867 lines
24 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
  4. /**********************************************************************/
  5. /*
  6. hArray.cpp
  7. Index manager for TAPI devices db
  8. FILE HISTORY:
  9. Dec 16 1997 EricDav Created
  10. */
  11. #include "stdafx.h"
  12. #include "harray.h"
  13. #include "mbstring.h"
  14. LPBYTE g_pStart;
  15. /*!--------------------------------------------------------------------------
  16. Class CHDeviceIndex
  17. ---------------------------------------------------------------------------*/
  18. CHDeviceIndex::CHDeviceIndex(INDEX_TYPE IndexType)
  19. : m_dbType(IndexType), m_bAscending(TRUE)
  20. {
  21. }
  22. CHDeviceIndex::~CHDeviceIndex()
  23. {
  24. }
  25. /*!--------------------------------------------------------------------------
  26. CHDeviceIndex::GetType
  27. -
  28. Author: EricDav
  29. ---------------------------------------------------------------------------*/
  30. HRESULT
  31. CHDeviceIndex::GetType(INDEX_TYPE * pIndexType)
  32. {
  33. if (pIndexType)
  34. *pIndexType = m_dbType;
  35. return hrOK;
  36. }
  37. /*!--------------------------------------------------------------------------
  38. CHDeviceIndex::SetArray
  39. -
  40. Author: EricDav
  41. ---------------------------------------------------------------------------*/
  42. HRESULT
  43. CHDeviceIndex::SetArray(HDeviceArray & hdeviceArray)
  44. {
  45. m_hdeviceArray.Copy(hdeviceArray);
  46. return hrOK;
  47. }
  48. /*!--------------------------------------------------------------------------
  49. CHDeviceIndex::GetHDevice
  50. -
  51. Author: EricDav
  52. ---------------------------------------------------------------------------*/
  53. HDEVICE
  54. CHDeviceIndex::GetHDevice(int nIndex)
  55. {
  56. Assert(nIndex >= 0);
  57. Assert(nIndex <= m_hdeviceArray.GetSize());
  58. if (nIndex < 0 ||
  59. nIndex >= m_hdeviceArray.GetSize())
  60. {
  61. return NULL;
  62. }
  63. return m_hdeviceArray.GetAt(nIndex);
  64. }
  65. /*!--------------------------------------------------------------------------
  66. CHDeviceIndex::GetIndex
  67. -
  68. Author: EricDav
  69. ---------------------------------------------------------------------------*/
  70. int
  71. CHDeviceIndex::GetIndex(HDEVICE hdevice)
  72. {
  73. Assert(hdevice != 0);
  74. LPHDEVICE phdevice = (LPHDEVICE) BSearch((const void *)&hdevice,
  75. (const void *)m_hdeviceArray.GetData(),
  76. (size_t)m_hdeviceArray.GetSize(),
  77. sizeof(HDEVICE));
  78. int nIndex = (int) (phdevice - (LPHDEVICE) m_hdeviceArray.GetData());
  79. Assert(nIndex >= 0);
  80. Assert(nIndex <= m_hdeviceArray.GetSize());
  81. int nComp, nIndexTemp;
  82. nComp = BCompare(&hdevice, phdevice);
  83. if (nComp == 0)
  84. {
  85. // found the right one, check the previous one to return the first
  86. // record in a list of duplicates
  87. nIndexTemp = nIndex;
  88. while (nIndexTemp && nComp == 0)
  89. {
  90. *phdevice = m_hdeviceArray.GetAt(--nIndexTemp);
  91. nComp = BCompare(&hdevice, phdevice);
  92. }
  93. if (nIndexTemp == nIndex)
  94. return nIndex; // nIndex should be zero here as well
  95. else
  96. if (nComp == 0)
  97. return nIndexTemp; // nIndexTemp should be 0 in this case
  98. else
  99. return nIndexTemp++;
  100. }
  101. return -1;
  102. }
  103. /*!--------------------------------------------------------------------------
  104. CHDeviceIndex::Add
  105. -
  106. Author: EricDav
  107. ---------------------------------------------------------------------------*/
  108. HRESULT
  109. CHDeviceIndex::Add(HDEVICE hdevice, BOOL bEnd)
  110. {
  111. // if we are loading the array then just stick this on the end
  112. if (bEnd)
  113. {
  114. m_hdeviceArray.Add(hdevice);
  115. }
  116. else
  117. {
  118. if (m_hdeviceArray.GetSize() == 0)
  119. {
  120. m_hdeviceArray.Add(hdevice);
  121. }
  122. else
  123. {
  124. LPHDEVICE phdevice = (LPHDEVICE) BSearch((const void *)&hdevice,
  125. (const void *)m_hdeviceArray.GetData(),
  126. (size_t)m_hdeviceArray.GetSize(),
  127. sizeof(HDEVICE));
  128. int nIndex = (int) (phdevice - (LPHDEVICE) m_hdeviceArray.GetData());
  129. Assert(nIndex >= 0);
  130. Assert(nIndex <= m_hdeviceArray.GetSize());
  131. int nComp = BCompare(&hdevice, phdevice);
  132. if (nComp < 0)
  133. {
  134. if(nIndex == 0)
  135. m_hdeviceArray.InsertAt(nIndex , hdevice);
  136. else // Insert before phdevice
  137. m_hdeviceArray.InsertAt(nIndex - 1, hdevice);
  138. }
  139. else
  140. {
  141. // insert after phdevice
  142. m_hdeviceArray.InsertAt(nIndex + 1, hdevice);
  143. }
  144. }
  145. }
  146. return hrOK;
  147. }
  148. /*!--------------------------------------------------------------------------
  149. CHDeviceIndex::Remove
  150. -
  151. Author: EricDav
  152. ---------------------------------------------------------------------------*/
  153. HRESULT
  154. CHDeviceIndex::Remove(HDEVICE hdevice)
  155. {
  156. // do a bsearch for the record and then remove
  157. LPHDEVICE phdevice = (LPHDEVICE) BSearch(&hdevice,
  158. m_hdeviceArray.GetData(),
  159. (size_t)m_hdeviceArray.GetSize(),
  160. sizeof(HDEVICE));
  161. int nComp = BCompare(&hdevice, phdevice);
  162. Assert(nComp == 0);
  163. if (nComp != 0)
  164. return E_FAIL;
  165. // calculate the index
  166. int nIndex = (int) (phdevice - (LPHDEVICE) m_hdeviceArray.GetData());
  167. Assert(nIndex >= 0);
  168. Assert(nIndex <= m_hdeviceArray.GetSize());
  169. m_hdeviceArray.RemoveAt(nIndex);
  170. return hrOK;
  171. }
  172. /*!--------------------------------------------------------------------------
  173. CHDeviceIndex::BSearch
  174. Modified bsearch which returns the closest or equal element in
  175. an array
  176. Author: EricDav
  177. ---------------------------------------------------------------------------*/
  178. void *
  179. CHDeviceIndex::BSearch (const void *key,
  180. const void *base,
  181. size_t num,
  182. size_t width)
  183. {
  184. char *lo = (char *)base;
  185. char *hi = (char *)base + (num - 1) * width;
  186. char *mid;
  187. unsigned int half;
  188. int result;
  189. while (lo <= hi)
  190. if (half = num / 2)
  191. {
  192. mid = lo + (num & 1 ? half : (half - 1)) * width;
  193. if (!(result = BCompare(key,mid)))
  194. return(mid);
  195. else if (result < 0)
  196. {
  197. hi = mid - width;
  198. num = num & 1 ? half : half-1;
  199. }
  200. else {
  201. lo = mid + width;
  202. num = half;
  203. }
  204. }
  205. else if (num)
  206. return(lo);
  207. else
  208. break;
  209. return(mid);
  210. }
  211. /*!--------------------------------------------------------------------------
  212. Class CIndexMgr
  213. ---------------------------------------------------------------------------*/
  214. CIndexMgr::CIndexMgr()
  215. {
  216. m_posCurrentProvider= NULL;
  217. }
  218. CIndexMgr::~CIndexMgr()
  219. {
  220. Reset();
  221. }
  222. /*!--------------------------------------------------------------------------
  223. CIndexMgr::Initialize
  224. -
  225. Author: EricDav
  226. ---------------------------------------------------------------------------*/
  227. HRESULT
  228. CIndexMgr::Initialize()
  229. {
  230. HRESULT hr = hrOK;
  231. CSingleLock cl(&m_cs);
  232. cl.Lock();
  233. COM_PROTECT_TRY
  234. {
  235. // cleanup
  236. Reset();
  237. }
  238. COM_PROTECT_CATCH
  239. return hr;
  240. }
  241. /*!--------------------------------------------------------------------------
  242. CIndexMgr::Reset
  243. -
  244. Author: EricDav
  245. ---------------------------------------------------------------------------*/
  246. HRESULT
  247. CIndexMgr::Reset()
  248. {
  249. CSingleLock cl(&m_cs);
  250. cl.Lock();
  251. while (m_listProviderIndex.GetCount() > 0)
  252. {
  253. CProviderIndexInfo * pProviderIndexInfo = m_listProviderIndex.RemoveHead();
  254. while (pProviderIndexInfo->m_listIndicies.GetCount() > 0)
  255. delete pProviderIndexInfo->m_listIndicies.RemoveHead();
  256. delete pProviderIndexInfo;
  257. }
  258. return hrOK;
  259. }
  260. /*!--------------------------------------------------------------------------
  261. CIndexMgr::GetTotalCount
  262. The index sorted by name contains the total database and should
  263. always be available. Use this for the total count.
  264. Author: EricDav
  265. ---------------------------------------------------------------------------*/
  266. UINT
  267. CIndexMgr::GetTotalCount()
  268. {
  269. CSingleLock cl(&m_cs);
  270. cl.Lock();
  271. UINT uTotalCount = 0;
  272. POSITION pos;
  273. pos = m_listProviderIndex.GetHeadPosition();
  274. while (pos)
  275. {
  276. CProviderIndexInfo * pProviderIndexInfo = m_listProviderIndex.GetNext(pos);
  277. if (pProviderIndexInfo->m_listIndicies.GetCount() > 0)
  278. uTotalCount += (UINT)(pProviderIndexInfo->m_listIndicies.GetHead())->GetArray().GetSize();
  279. }
  280. return uTotalCount;
  281. }
  282. /*!--------------------------------------------------------------------------
  283. CIndexMgr::GetCurrentCount
  284. The current count may differ depending upon if the current Index
  285. is a filtered index.
  286. Author: EricDav
  287. ---------------------------------------------------------------------------*/
  288. UINT
  289. CIndexMgr::GetCurrentCount()
  290. {
  291. CSingleLock cl(&m_cs);
  292. cl.Lock();
  293. CProviderIndexInfo * pProviderIndexInfo = NULL;
  294. CHDeviceIndex * pIndex = NULL;
  295. pProviderIndexInfo = m_listProviderIndex.GetAt(m_posCurrentProvider);
  296. pIndex = pProviderIndexInfo->m_listIndicies.GetAt(pProviderIndexInfo->m_posCurrentIndex);
  297. if (pIndex == NULL)
  298. return 0;
  299. return (UINT)pIndex->GetArray().GetSize();
  300. }
  301. /*!--------------------------------------------------------------------------
  302. CIndexMgr::AddHDevice
  303. -
  304. Author: EricDav
  305. ---------------------------------------------------------------------------*/
  306. HRESULT
  307. CIndexMgr::AddHDevice(DWORD dwProviderID, HDEVICE hdevice, BOOL bEnd)
  308. {
  309. CSingleLock cl(&m_cs);
  310. cl.Lock();
  311. HRESULT hr = hrOK;
  312. CProviderIndexInfo * pProviderIndexInfo = NULL;
  313. CHDeviceIndex * pIndex = NULL;
  314. COM_PROTECT_TRY
  315. {
  316. // set current provider set the current provider position and if
  317. // the provider doesn't exist, it will create one
  318. hr = SetCurrentProvider(dwProviderID);
  319. if (FAILED(hr))
  320. return hr;
  321. pProviderIndexInfo = m_listProviderIndex.GetAt(m_posCurrentProvider);
  322. pIndex = pProviderIndexInfo->m_listIndicies.GetAt(pProviderIndexInfo->m_posCurrentIndex);
  323. if (pIndex)
  324. pIndex->Add(hdevice, bEnd);
  325. }
  326. COM_PROTECT_CATCH
  327. return hr;
  328. }
  329. /*!--------------------------------------------------------------------------
  330. CIndexMgr::RemoveHDevice
  331. -
  332. Author: EricDav
  333. ---------------------------------------------------------------------------*/
  334. HRESULT
  335. CIndexMgr::RemoveHDevice(DWORD dwProviderID, HDEVICE hdevice)
  336. {
  337. CSingleLock cl(&m_cs);
  338. cl.Lock();
  339. HRESULT hr = hrOK;
  340. CProviderIndexInfo * pProviderIndexInfo = NULL;
  341. CHDeviceIndex * pIndex = NULL;
  342. COM_PROTECT_TRY
  343. {
  344. hr = SetCurrentProvider(dwProviderID);
  345. if (FAILED(hr))
  346. return hr;
  347. pProviderIndexInfo = m_listProviderIndex.GetAt(m_posCurrentProvider);
  348. pIndex = pProviderIndexInfo->m_listIndicies.GetAt(pProviderIndexInfo->m_posCurrentIndex);
  349. if (pIndex)
  350. pIndex->Remove(hdevice);
  351. }
  352. COM_PROTECT_CATCH
  353. return hr;
  354. }
  355. /*!--------------------------------------------------------------------------
  356. CIndexMgr::Sort
  357. -
  358. Author: EricDav
  359. ---------------------------------------------------------------------------*/
  360. HRESULT
  361. CIndexMgr::Sort(DWORD dwProviderID, INDEX_TYPE SortType, DWORD dwSortOptions, LPBYTE pStart)
  362. {
  363. CSingleLock cl(&m_cs);
  364. cl.Lock();
  365. HRESULT hr = hrOK;
  366. CHDeviceIndex * pNameIndex;
  367. CHDeviceIndex * pNewIndex;
  368. POSITION pos, posLast;
  369. INDEX_TYPE indexType;
  370. BOOL bAscending = (dwSortOptions & SORT_ASCENDING) ? TRUE : FALSE;
  371. hr = SetCurrentProvider(dwProviderID);
  372. if (FAILED(hr))
  373. return hr;
  374. // check to see if we have an index for this.
  375. CProviderIndexInfo * pProviderIndexInfo = m_listProviderIndex.GetAt(m_posCurrentProvider);
  376. pos = pProviderIndexInfo->m_listIndicies.GetHeadPosition();
  377. while (pos)
  378. {
  379. posLast = pos;
  380. CHDeviceIndex * pIndex = pProviderIndexInfo->m_listIndicies.GetNext(pos);
  381. pIndex->GetType(&indexType);
  382. // the index for this type already exists, just sort accordingly
  383. if (indexType == SortType)
  384. {
  385. if (pIndex->IsAscending() != bAscending)
  386. {
  387. pIndex->SetAscending(bAscending);
  388. pIndex->Sort(pStart);
  389. }
  390. pProviderIndexInfo->m_posCurrentIndex = posLast;
  391. return hrOK;
  392. }
  393. }
  394. // to save memory, remove all old indicies, except the name index
  395. //CleanupIndicies();
  396. // if not, create one
  397. switch (SortType)
  398. {
  399. case INDEX_TYPE_NAME:
  400. pNewIndex = new CIndexName();
  401. break;
  402. case INDEX_TYPE_USERS:
  403. pNewIndex = new CIndexUsers();
  404. break;
  405. case INDEX_TYPE_STATUS:
  406. pNewIndex = new CIndexStatus();
  407. break;
  408. default:
  409. Panic1("Invalid sort type passed to IndexMgr::Sort %d\n", SortType);
  410. break;
  411. }
  412. Assert(pNewIndex);
  413. // name index is always the first in the list
  414. pNameIndex = pProviderIndexInfo->m_listIndicies.GetHead();
  415. Assert(pNameIndex);
  416. // copy the array from the named index
  417. pNewIndex->SetArray(pNameIndex->GetArray());
  418. pNewIndex->SetAscending(bAscending);
  419. pNewIndex->Sort(pStart);
  420. pProviderIndexInfo->m_posCurrentIndex = pProviderIndexInfo->m_listIndicies.AddTail(pNewIndex);
  421. return hr;
  422. }
  423. /*!--------------------------------------------------------------------------
  424. CIndexMgr::CleanupIndicies
  425. Removes all indicies except the name index, and a filtered view
  426. Author: EricDav
  427. ---------------------------------------------------------------------------*/
  428. void
  429. CIndexMgr::CleanupIndicies()
  430. {
  431. CSingleLock cl(&m_cs);
  432. cl.Lock();
  433. INDEX_TYPE indexType;
  434. CProviderIndexInfo * pProviderIndexInfo = m_listProviderIndex.GetAt(m_posCurrentProvider);
  435. POSITION pos = pProviderIndexInfo->m_listIndicies.GetHeadPosition();
  436. while (pos)
  437. {
  438. POSITION posLast = pos;
  439. CHDeviceIndex * pIndex = pProviderIndexInfo->m_listIndicies.GetNext(pos);
  440. pIndex->GetType(&indexType);
  441. if (indexType == INDEX_TYPE_NAME)
  442. continue;
  443. pProviderIndexInfo->m_listIndicies.RemoveAt(posLast);
  444. delete pIndex;
  445. }
  446. }
  447. /*!--------------------------------------------------------------------------
  448. CIndexMgr::GetHDevice
  449. Returns an hdevice based on an index into the current sorted list
  450. Author: EricDav
  451. ---------------------------------------------------------------------------*/
  452. HRESULT
  453. CIndexMgr::GetHDevice(DWORD dwProviderID, int nIndex, LPHDEVICE phdevice)
  454. {
  455. CSingleLock cl(&m_cs);
  456. cl.Lock();
  457. SetCurrentProvider(dwProviderID);
  458. CProviderIndexInfo * pProviderIndexInfo = m_listProviderIndex.GetAt(m_posCurrentProvider);
  459. CHDeviceIndex * pIndex = pProviderIndexInfo->m_listIndicies.GetAt(pProviderIndexInfo->m_posCurrentIndex);
  460. Assert(pIndex);
  461. if (phdevice)
  462. *phdevice = pIndex->GetHDevice(nIndex);
  463. return hrOK;
  464. }
  465. /*!--------------------------------------------------------------------------
  466. CIndexMgr::GetIndex
  467. Returns the index of an hlien from the current sorted list
  468. Author: EricDav
  469. ---------------------------------------------------------------------------*/
  470. HRESULT
  471. CIndexMgr::GetIndex(DWORD dwProviderID, HDEVICE hdevice, int * pnIndex)
  472. {
  473. CSingleLock cl(&m_cs);
  474. cl.Lock();
  475. SetCurrentProvider(dwProviderID);
  476. CProviderIndexInfo * pProviderIndexInfo = m_listProviderIndex.GetAt(m_posCurrentProvider);
  477. CHDeviceIndex * pIndex = pProviderIndexInfo->m_listIndicies.GetAt(pProviderIndexInfo->m_posCurrentIndex);
  478. Assert(pIndex);
  479. if (pIndex)
  480. *pnIndex = pIndex->GetIndex(hdevice);
  481. return hrOK;
  482. }
  483. /*!--------------------------------------------------------------------------
  484. CIndexMgr::SetCurrentProvider
  485. Sets the current provider for the index mgr, if it doesn't exist,
  486. it is created
  487. Author: EricDav
  488. ---------------------------------------------------------------------------*/
  489. HRESULT
  490. CIndexMgr::SetCurrentProvider(DWORD dwProviderID)
  491. {
  492. HRESULT hr = hrOK;
  493. BOOL bExists = FALSE;
  494. POSITION posLast;
  495. COM_PROTECT_TRY
  496. {
  497. POSITION pos = m_listProviderIndex.GetHeadPosition();
  498. while (pos)
  499. {
  500. posLast = pos;
  501. CProviderIndexInfo * pProviderIndexInfo = m_listProviderIndex.GetNext(pos);
  502. // is the the correct provider to add this to?
  503. if (pProviderIndexInfo->m_dwProviderID != dwProviderID)
  504. continue;
  505. m_posCurrentProvider = posLast;
  506. bExists = TRUE;
  507. }
  508. if (!bExists)
  509. {
  510. // no provider index exists for this. Create one now.
  511. CProviderIndexInfo * pProviderIndexInfo = new CProviderIndexInfo;
  512. pProviderIndexInfo->m_dwProviderID = dwProviderID;
  513. CHDeviceIndex * pIndex = new CIndexName;
  514. pProviderIndexInfo->m_posCurrentIndex = pProviderIndexInfo->m_listIndicies.AddHead(pIndex);
  515. m_posCurrentProvider = m_listProviderIndex.AddTail(pProviderIndexInfo);
  516. }
  517. }
  518. COM_PROTECT_CATCH
  519. return hr;
  520. }
  521. /*!--------------------------------------------------------------------------
  522. Class CIndexName
  523. ---------------------------------------------------------------------------*/
  524. /*!--------------------------------------------------------------------------
  525. CIndexName::BCompare
  526. -
  527. Author: EricDav
  528. ---------------------------------------------------------------------------*/
  529. int
  530. CIndexName::BCompare(const void * elem1, const void * elem2)
  531. {
  532. int nRet;
  533. LPHDEVICE phdevice1 = (LPHDEVICE) elem1;
  534. LPHDEVICE phdevice2 = (LPHDEVICE) elem2;
  535. LPDEVICEINFO pRec1 = (LPDEVICEINFO) *phdevice1;
  536. LPDEVICEINFO pRec2 = (LPDEVICEINFO) *phdevice2;
  537. nRet = lstrcmp((LPCTSTR) (g_pStart + pRec1->dwDeviceNameOffset), (LPCTSTR) (g_pStart + pRec2->dwDeviceNameOffset));
  538. if (nRet == 0)
  539. {
  540. // permanent device IDs should be unique
  541. if (pRec1->dwPermanentDeviceID > pRec2->dwPermanentDeviceID)
  542. nRet = 1;
  543. else
  544. nRet = -1;
  545. }
  546. return nRet;
  547. }
  548. /*!--------------------------------------------------------------------------
  549. CIndexName::Sort
  550. -
  551. Author: EricDav
  552. ---------------------------------------------------------------------------*/
  553. HRESULT
  554. CIndexName::Sort(LPBYTE pStart)
  555. {
  556. // save the base pointer for later
  557. g_pStart = pStart;
  558. if (m_bAscending)
  559. qsort(m_hdeviceArray.GetData(), (size_t)m_hdeviceArray.GetSize(), sizeof(HDEVICE), QCompareA);
  560. else
  561. qsort(m_hdeviceArray.GetData(), (size_t)m_hdeviceArray.GetSize(), sizeof(HDEVICE), QCompareD);
  562. return hrOK;
  563. }
  564. /*!--------------------------------------------------------------------------
  565. CIndexName::QCompare
  566. -
  567. Author: EricDav
  568. ---------------------------------------------------------------------------*/
  569. int __cdecl
  570. CIndexName::QCompareA(const void * elem1, const void * elem2)
  571. {
  572. int nRet;
  573. LPHDEVICE phdevice1 = (LPHDEVICE) elem1;
  574. LPHDEVICE phdevice2 = (LPHDEVICE) elem2;
  575. LPDEVICEINFO pRec1 = (LPDEVICEINFO) *phdevice1;
  576. LPDEVICEINFO pRec2 = (LPDEVICEINFO) *phdevice2;
  577. nRet = lstrcmp((LPCTSTR) (g_pStart + pRec1->dwDeviceNameOffset), (LPCTSTR) (g_pStart + pRec2->dwDeviceNameOffset));
  578. if (nRet == 0)
  579. {
  580. // permanent device IDs should be unique
  581. if (pRec1->dwPermanentDeviceID > pRec2->dwPermanentDeviceID)
  582. nRet = 1;
  583. else
  584. nRet = -1;
  585. }
  586. return nRet;
  587. }
  588. int __cdecl
  589. CIndexName::QCompareD(const void * elem1, const void * elem2)
  590. {
  591. return -QCompareA(elem1, elem2);
  592. }
  593. /*!--------------------------------------------------------------------------
  594. Class CIndexUsers
  595. ---------------------------------------------------------------------------*/
  596. /*!--------------------------------------------------------------------------
  597. CIndexUsers::BCompare
  598. -
  599. Author: EricDav
  600. ---------------------------------------------------------------------------*/
  601. int
  602. CIndexUsers::BCompare(const void * elem1, const void * elem2)
  603. {
  604. int nRet;
  605. LPHDEVICE phdevice1 = (LPHDEVICE) elem1;
  606. LPHDEVICE phdevice2 = (LPHDEVICE) elem2;
  607. LPDEVICEINFO pRec1 = (LPDEVICEINFO) *phdevice1;
  608. LPDEVICEINFO pRec2 = (LPDEVICEINFO) *phdevice2;
  609. nRet = lstrcmp((LPCTSTR) (g_pStart + pRec1->dwDomainUserNamesOffset), (LPCTSTR) (g_pStart + pRec2->dwDomainUserNamesOffset));
  610. if (nRet == 0)
  611. nRet = lstrcmp((LPCTSTR) (g_pStart + pRec1->dwDeviceNameOffset), (LPCTSTR) (g_pStart + pRec2->dwDeviceNameOffset));
  612. return nRet;
  613. }
  614. /*!--------------------------------------------------------------------------
  615. CIndexUsers::Sort
  616. -
  617. Author: EricDav
  618. ---------------------------------------------------------------------------*/
  619. HRESULT
  620. CIndexUsers::Sort(LPBYTE pStart)
  621. {
  622. // save the base pointer for later
  623. g_pStart = pStart;
  624. if (m_bAscending)
  625. qsort(m_hdeviceArray.GetData(), (size_t)m_hdeviceArray.GetSize(), sizeof(HDEVICE), QCompareA);
  626. else
  627. qsort(m_hdeviceArray.GetData(), (size_t)m_hdeviceArray.GetSize(), sizeof(HDEVICE), QCompareD);
  628. return hrOK;
  629. }
  630. /*!--------------------------------------------------------------------------
  631. CIndexUsers::QCompare
  632. -
  633. Author: EricDav
  634. ---------------------------------------------------------------------------*/
  635. int __cdecl
  636. CIndexUsers::QCompareA(const void * elem1, const void * elem2)
  637. {
  638. int nRet;
  639. LPHDEVICE phdevice1 = (LPHDEVICE) elem1;
  640. LPHDEVICE phdevice2 = (LPHDEVICE) elem2;
  641. LPDEVICEINFO pRec1 = (LPDEVICEINFO) *phdevice1;
  642. LPDEVICEINFO pRec2 = (LPDEVICEINFO) *phdevice2;
  643. nRet = lstrcmp((LPCTSTR) (g_pStart + pRec1->dwDomainUserNamesOffset), (LPCTSTR) (g_pStart + pRec2->dwDomainUserNamesOffset));
  644. if (nRet == 0)
  645. nRet = lstrcmp((LPCTSTR) (g_pStart + pRec1->dwDeviceNameOffset), (LPCTSTR) (g_pStart + pRec2->dwDeviceNameOffset));
  646. return nRet;
  647. }
  648. int __cdecl
  649. CIndexUsers::QCompareD(const void * elem1, const void * elem2)
  650. {
  651. return -QCompareA(elem1, elem2);
  652. }
  653. /*!--------------------------------------------------------------------------
  654. Class CIndexStatus
  655. ---------------------------------------------------------------------------*/
  656. /*!--------------------------------------------------------------------------
  657. CIndexStatus::BCompare
  658. -
  659. Author: EricDav
  660. ---------------------------------------------------------------------------*/
  661. int
  662. CIndexStatus::BCompare(const void * elem1, const void * elem2)
  663. {
  664. LPHDEVICE phdevice1 = (LPHDEVICE) elem1;
  665. LPHDEVICE phdevice2 = (LPHDEVICE) elem2;
  666. LPDEVICEINFO pRec1 = (LPDEVICEINFO) *phdevice1;
  667. LPDEVICEINFO pRec2 = (LPDEVICEINFO) *phdevice2;
  668. //return _mbscmp((const PUCHAR) &pRec1->szRecordName[0], (const PUCHAR) &pRec2->szRecordName[0]);
  669. return 0;
  670. }
  671. /*!--------------------------------------------------------------------------
  672. CIndexStatus::Sort
  673. -
  674. Author: EricDav
  675. ---------------------------------------------------------------------------*/
  676. HRESULT
  677. CIndexStatus::Sort(LPBYTE pStart)
  678. {
  679. // save the base pointer for later
  680. g_pStart = pStart;
  681. if (m_bAscending)
  682. qsort(m_hdeviceArray.GetData(), (size_t)m_hdeviceArray.GetSize(), sizeof(HDEVICE), QCompareA);
  683. else
  684. qsort(m_hdeviceArray.GetData(), (size_t)m_hdeviceArray.GetSize(), sizeof(HDEVICE), QCompareD);
  685. return hrOK;
  686. }
  687. /*!--------------------------------------------------------------------------
  688. CIndexIpAddr::QCompare
  689. -
  690. Author: EricDav
  691. ---------------------------------------------------------------------------*/
  692. int __cdecl
  693. CIndexStatus::QCompareA(const void * elem1, const void * elem2)
  694. {
  695. LPHDEVICE phdevice1 = (LPHDEVICE) elem1;
  696. LPHDEVICE phdevice2 = (LPHDEVICE) elem2;
  697. LPHDEVICE pRec1 = (LPHDEVICE) *phdevice1;
  698. LPHDEVICE pRec2 = (LPHDEVICE) *phdevice2;
  699. //return lstrcmp((LPCTSTR) (g_pStart + pRec1->dwDeviceNameOffset), (LPCTSTR) (g_pStart + pRec2->dwDeviceNameOffset));
  700. return 0;
  701. }
  702. int __cdecl
  703. CIndexStatus::QCompareD(const void * elem1, const void * elem2)
  704. {
  705. return -QCompareA(elem1, elem2);
  706. }