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.

2231 lines
50 KiB

  1. /*++
  2. Copyright (C) 1996-2001 Microsoft Corporation
  3. Module Name:
  4. Main.cpp
  5. Abstract:
  6. History:
  7. --*/
  8. #include <precomp.h>
  9. #include <objbase.h>
  10. #include <stdio.h>
  11. #include <wbemint.h>
  12. #include <Thread.h>
  13. #include <HelperFuncs.h>
  14. #include <Logging.h>
  15. #include "Globals.h"
  16. #include "CGlobals.h"
  17. #include "classfac.h"
  18. #include "ProvLoad.h"
  19. #include "ProvAggr.h"
  20. #include "ProvHost.h"
  21. #include "guids.h"
  22. #include "Main.h"
  23. #include <locale.h>
  24. #include <helper.h>
  25. /******************************************************************************
  26. *
  27. * Name:
  28. *
  29. *
  30. * Description:
  31. *
  32. *
  33. *****************************************************************************/
  34. #define PROVIDER_HOST_DLL_TIMEOUT (10*1000) // 10 seconds
  35. #define VALIDATE_HEAP {};
  36. #ifdef DEV_BUILD
  37. #ifdef _X86_
  38. ////////////////////////////////////////////////////////
  39. class ValidateHeap : public EventHandler
  40. {
  41. BOOL (* rtlValidateProcessHeaps)(void);
  42. public:
  43. ValidateHeap () ;
  44. int handleTimeout (void) ;
  45. void validateHeap();
  46. } heapValidator;
  47. #undef VALIDATE_HEAP
  48. #define VALIDATE_HEAP {heapValidator.validateHeap(); };
  49. ValidateHeap::ValidateHeap()
  50. {
  51. FARPROC OldRoutine = GetProcAddress(GetModuleHandleW(L"NTDLL"),"RtlValidateProcessHeaps");
  52. rtlValidateProcessHeaps = reinterpret_cast<BOOL (*)(void)>(OldRoutine) ;
  53. }
  54. int
  55. ValidateHeap::handleTimeout (void)
  56. {
  57. validateHeap();
  58. return 0;
  59. }
  60. void
  61. ValidateHeap::validateHeap (void)
  62. {
  63. //NtCurrentPeb()->BeingDebugged = 1;
  64. if (rtlValidateProcessHeaps)
  65. {
  66. if ((*rtlValidateProcessHeaps)()==FALSE)
  67. DebugBreak();
  68. }
  69. //NtCurrentPeb()->BeingDebugged = 0;
  70. }
  71. ////////////////////////////////////////////////////////
  72. #include <malloc.h>
  73. struct HEAP_ENTRY {
  74. WORD Size;
  75. WORD PrevSize;
  76. BYTE SegmentIndex;
  77. BYTE Flags;
  78. BYTE UnusedBytes;
  79. BYTE SmallTagIndex;
  80. };
  81. #define HEAP_SLOW_FLAGS 0x7d030f60
  82. // only the "header"
  83. typedef struct _HEAP {
  84. HEAP_ENTRY Entry;
  85. ULONG Signature;
  86. ULONG Flags;
  87. ULONG ForceFlags;
  88. } HEAP;
  89. BOOL g_FaultHeapEnabled = FALSE;
  90. BOOL g_FaultFileEnabled = FALSE;
  91. ULONG g_Seed;
  92. ULONG g_Factor = 100000;
  93. ULONG g_Percent = 0x20;
  94. //ULONG g_RowOfFailures = 5;
  95. //LONG g_NumFailInARow = 0;
  96. //LONG g_NumFailedAllocation = 0;
  97. BOOL g_bDisableBreak = FALSE;
  98. BOOL g_ExitProcessCalled = FALSE;
  99. LONG g_Index = -1;
  100. class CS_ : public CRITICAL_SECTION
  101. {
  102. public:
  103. CS_(){InitializeCriticalSection(this);};
  104. ~CS_(){DeleteCriticalSection(this);};
  105. } g_CS;
  106. #define MAX_OPERATIONS (1024*8)
  107. typedef struct _FinalOperations
  108. {
  109. enum OpType
  110. {
  111. Delete = 'eerF',
  112. Alloc = 'ollA',
  113. ReAlloc = 'lAeR',
  114. Destroy = 'tseD',
  115. Create = 'aerC'
  116. };
  117. OpType m_OpType;
  118. ULONG_PTR m_Addr;
  119. PVOID m_Stack[6];
  120. } FinalOperations;
  121. /*
  122. FinalOperations g_FinalOp[MAX_OPERATIONS];
  123. VOID SetFinalOp(FinalOperations::OpType Type,
  124. ULONG_PTR Addr)
  125. {
  126. if (!g_ExitProcessCalled)
  127. return;
  128. if (g_bDisableBreak)
  129. return;
  130. ULONG * pDW = (ULONG *)_alloca(sizeof(ULONG));
  131. LONG NewIndex = InterlockedIncrement(&g_Index);
  132. NewIndex %= MAX_OPERATIONS;
  133. //if (g_Index >= MAX_OPERATIONS)
  134. //{
  135. // InterlockedIncrement(&g_IndexRot);
  136. //}
  137. g_FinalOp[NewIndex].m_OpType = Type;
  138. g_FinalOp[NewIndex].m_Addr = Addr;
  139. RtlCaptureStackBackTrace(2,
  140. 6,
  141. (PVOID *)g_FinalOp[NewIndex].m_Stack,
  142. pDW);
  143. }
  144. */
  145. #define SIZE_JUMP_ADR 5
  146. #define SIZE_SAVED_INSTR 12
  147. void
  148. _declspec(naked) Prolog__ReadFile(){
  149. _asm {
  150. // this is the space for the "saved istructions"
  151. nop ;
  152. nop ;
  153. nop ;
  154. nop ;
  155. nop ;
  156. nop ;
  157. nop ;
  158. nop ;
  159. nop ;
  160. nop ;
  161. nop ;
  162. nop ;
  163. // this is the place for the JMP
  164. nop ;
  165. nop ;
  166. nop ;
  167. nop ;
  168. nop ;
  169. nop ; // dist
  170. nop ; // dist
  171. nop ; // dist
  172. nop ; // dist
  173. }
  174. }
  175. BOOL _I_ReadFile(
  176. HANDLE hFile, // handle to file
  177. LPVOID lpBuffer, // data buffer
  178. DWORD nNumberOfBytesToRead, // number of bytes to read
  179. LPDWORD lpNumberOfBytesRead, // number of bytes read
  180. LPOVERLAPPED lpOverlapped // offset
  181. ){
  182. DWORD * pDw = (DWORD *)_alloca(sizeof(DWORD));
  183. BOOL bRet;
  184. LONG Ret = RtlRandomEx(&g_Seed);
  185. if (g_FaultFileEnabled && (Ret%g_Factor < g_Percent))
  186. {
  187. if (lpNumberOfBytesRead)
  188. *lpNumberOfBytesRead = 0;
  189. return FALSE;
  190. }
  191. _asm{
  192. push lpOverlapped;
  193. push lpNumberOfBytesRead;
  194. push nNumberOfBytesToRead;
  195. push lpBuffer;
  196. push hFile;
  197. call Prolog__ReadFile;
  198. mov bRet,eax
  199. }
  200. return bRet;
  201. }
  202. void
  203. _declspec(naked) Prolog__WriteFile(){
  204. _asm {
  205. // this is the space for the "saved istructions"
  206. nop ;
  207. nop ;
  208. nop ;
  209. nop ;
  210. nop ;
  211. nop ;
  212. nop ;
  213. nop ;
  214. nop ;
  215. nop ;
  216. nop ;
  217. nop ;
  218. // this is the place for the JMP
  219. nop ;
  220. nop ;
  221. nop ;
  222. nop ;
  223. nop ;
  224. nop ; // dist
  225. nop ; // dist
  226. nop ; // dist
  227. }
  228. }
  229. BOOL _I_WriteFile(
  230. HANDLE hFile, // handle to file
  231. LPCVOID lpBuffer, // data buffer
  232. DWORD nNumberOfBytesToWrite, // number of bytes to write
  233. LPDWORD lpNumberOfBytesWritten, // number of bytes written
  234. LPOVERLAPPED lpOverlapped // overlapped buffer
  235. ){
  236. DWORD * pDw = (DWORD *)_alloca(sizeof(DWORD));
  237. BOOL bRet;
  238. LONG Ret = RtlRandomEx(&g_Seed);
  239. if (g_FaultFileEnabled && (Ret%g_Factor < g_Percent))
  240. {
  241. if (lpNumberOfBytesWritten)
  242. *lpNumberOfBytesWritten = 0;
  243. return FALSE;
  244. }
  245. _asm{
  246. push lpOverlapped;
  247. push lpNumberOfBytesWritten;
  248. push nNumberOfBytesToWrite;
  249. push lpBuffer;
  250. push hFile;
  251. call Prolog__WriteFile;
  252. mov bRet,eax
  253. }
  254. return bRet;
  255. }
  256. void
  257. _declspec(naked) Prolog__CreateEvent(){
  258. _asm {
  259. // this is the space for the "saved istructions"
  260. nop ;
  261. nop ;
  262. nop ;
  263. nop ;
  264. nop ;
  265. nop ;
  266. nop ;
  267. nop ;
  268. nop ;
  269. nop ;
  270. nop ;
  271. nop ;
  272. // this is the place for the JMP
  273. nop ;
  274. nop ;
  275. nop ;
  276. nop ;
  277. nop ;
  278. nop ; // dist
  279. nop ; // dist
  280. }
  281. }
  282. HANDLE _I_CreateEvent(
  283. LPSECURITY_ATTRIBUTES lpEventAttributes, // SD
  284. BOOL bManualReset, // reset type
  285. BOOL bInitialState, // initial state
  286. LPCWSTR lpName // object name
  287. )
  288. {
  289. DWORD * pDw = (DWORD *)_alloca(sizeof(DWORD));
  290. HANDLE hHandle;
  291. LONG Ret = RtlRandomEx(&g_Seed);
  292. if (g_FaultFileEnabled && (Ret%g_Factor < g_Percent))
  293. {
  294. return NULL;
  295. }
  296. _asm{
  297. push lpName;
  298. push bInitialState;
  299. push bManualReset;
  300. push lpEventAttributes
  301. call Prolog__CreateEvent;
  302. mov hHandle,eax
  303. }
  304. return hHandle;
  305. }
  306. void
  307. _declspec(naked) Prolog__RtlFreeHeap(){
  308. _asm {
  309. // this is the space for the "saved istructions"
  310. nop ;
  311. nop ;
  312. nop ;
  313. nop ;
  314. nop ;
  315. nop ;
  316. nop ;
  317. nop ;
  318. nop ;
  319. nop ;
  320. nop ;
  321. nop ;
  322. // this is the place for the JMP
  323. nop ;
  324. nop ;
  325. nop ;
  326. nop ;
  327. nop ;
  328. }
  329. }
  330. #define SPACE_STACK_ALLOC (4*sizeof(ULONG_PTR))
  331. DWORD _I_RtlFreeHeap(VOID * pHeap,DWORD Flags,VOID * pBlock)
  332. {
  333. ULONG * pLong = (ULONG *)_alloca(sizeof(DWORD));
  334. Flags |= (((HEAP *)pHeap)->Flags) | (((HEAP *)pHeap)->ForceFlags);
  335. DWORD dwRet;
  336. if (pBlock && !(HEAP_SLOW_FLAGS & Flags))
  337. {
  338. HEAP_ENTRY * pEntry = (HEAP_ENTRY *)pBlock-1;
  339. DWORD RealSize = pEntry->Size * sizeof(HEAP_ENTRY);
  340. DWORD Size = RealSize - pEntry->UnusedBytes;
  341. ULONG_PTR * pL = (ULONG_PTR *)pBlock;
  342. if (0 == (pEntry->Flags & 0x01) ||0xf0f0f0f0 == pL[1] )
  343. {
  344. if (!g_bDisableBreak)
  345. DebugBreak();
  346. }
  347. //memset(pBlock,0xF0,RealSize-SPACE_STACK_ALLOC-sizeof(HEAP_ENTRY));
  348. DWORD CanMemset = RealSize-sizeof(HEAP_ENTRY);
  349. memset(pBlock,0xF0,(CanMemset > SPACE_STACK_ALLOC)?CanMemset-SPACE_STACK_ALLOC:CanMemset);
  350. if (pEntry->Size >=4)
  351. {
  352. RtlCaptureStackBackTrace (1,
  353. 4,
  354. (PVOID *)(pEntry+2),
  355. pLong);
  356. }
  357. }
  358. _asm {
  359. push pBlock ;
  360. push Flags ;
  361. push pHeap ;
  362. call Prolog__RtlFreeHeap ;
  363. mov dwRet,eax ;
  364. }
  365. //SetFinalOp(FinalOperations::Delete,(ULONG_PTR)pBlock);
  366. return dwRet;
  367. }
  368. void
  369. _declspec(naked) Prolog__RtlAllocateHeap(){
  370. _asm {
  371. // this is the space for the "saved istructions"
  372. nop ;
  373. nop ;
  374. nop ;
  375. nop ;
  376. nop ;
  377. nop ;
  378. nop ;
  379. nop ;
  380. nop ;
  381. nop ;
  382. nop ;
  383. nop ;
  384. // this is the place for the JMP
  385. nop ;
  386. nop ;
  387. nop ;
  388. nop ;
  389. nop ;
  390. nop ; // to make this distinct
  391. }
  392. }
  393. VOID * _I_RtlAllocateHeap(VOID * pHeap,DWORD Flags,DWORD Size)
  394. {
  395. //Size+=0x1000;
  396. ULONG * pLong = (ULONG *)_alloca(sizeof(DWORD));
  397. Flags |= (((HEAP *)pHeap)->Flags) | (((HEAP *)pHeap)->ForceFlags);
  398. VOID * pRet;
  399. DWORD NewSize = (Size < (3*sizeof(HEAP_ENTRY)))?(3*sizeof(HEAP_ENTRY)+SPACE_STACK_ALLOC):(Size+SPACE_STACK_ALLOC);
  400. // if (g_FaultHeapEnabled && g_NumFailInARow)
  401. // {
  402. // InterlockedDecrement(&g_NumFailInARow);
  403. // goto here;
  404. // }
  405. LONG Ret = RtlRandomEx(&g_Seed);
  406. if (g_FaultHeapEnabled && (Ret%g_Factor < g_Percent))
  407. {
  408. // g_NumFailInARow = g_RowOfFailures;
  409. //here:
  410. // InterlockedIncrement(&g_NumFailedAllocation);
  411. return NULL;
  412. }
  413. _asm {
  414. push NewSize ;
  415. push Flags ;
  416. push pHeap ;
  417. call Prolog__RtlAllocateHeap ;
  418. mov pRet,eax ;
  419. }
  420. //SetFinalOp(FinalOperations::Alloc,(ULONG_PTR)pRet);
  421. if (pRet && !(HEAP_SLOW_FLAGS & Flags) )
  422. {
  423. if (NewSize <= 0xffff)
  424. NewSize = sizeof(HEAP_ENTRY)*((HEAP_ENTRY *)pRet-1)->Size;
  425. if (!(HEAP_ZERO_MEMORY & Flags))
  426. {
  427. memset(pRet,0xc0,NewSize-sizeof(HEAP_ENTRY));
  428. }
  429. RtlCaptureStackBackTrace(1,
  430. 4,
  431. (PVOID *)((BYTE *)pRet+(NewSize-SPACE_STACK_ALLOC-sizeof(HEAP_ENTRY))),
  432. pLong);
  433. }
  434. return pRet;
  435. }
  436. void
  437. _declspec(naked) Prolog__RtlReAllocateHeap(){
  438. _asm {
  439. // this is the space for the "saved istructions"
  440. nop ;
  441. nop ;
  442. nop ;
  443. nop ;
  444. nop ;
  445. nop ;
  446. nop ;
  447. nop ;
  448. nop ;
  449. nop ;
  450. nop ;
  451. nop ;
  452. // this is the place for the JMP
  453. nop ;
  454. nop ;
  455. nop ;
  456. nop ;
  457. nop ;
  458. nop ; // dist
  459. nop ; // dist
  460. nop ; // dist
  461. nop ; // dist
  462. nop ; // dist
  463. }
  464. }
  465. VOID *
  466. _I_RtlReAllocateHeap(
  467. HANDLE pHeap, // handle to heap block
  468. DWORD Flags, // heap reallocation options
  469. LPVOID lpMem, // pointer to memory to reallocate
  470. SIZE_T Size // number of bytes to reallocate
  471. ){
  472. ULONG * pLong = (ULONG *)_alloca(sizeof(DWORD));
  473. Flags |= (((HEAP *)pHeap)->Flags) | (((HEAP *)pHeap)->ForceFlags);
  474. VOID * pRet;
  475. DWORD NewSize = (Size < (3*sizeof(HEAP_ENTRY)))?(3*sizeof(HEAP_ENTRY)+SPACE_STACK_ALLOC):(Size+SPACE_STACK_ALLOC);
  476. _asm {
  477. push NewSize ;
  478. push lpMem ;
  479. push Flags ;
  480. push pHeap ;
  481. call Prolog__RtlReAllocateHeap ;
  482. mov pRet,eax ;
  483. }
  484. //SetFinalOp(FinalOperations::ReAlloc,(ULONG_PTR)pRet);
  485. if (pRet && !(HEAP_SLOW_FLAGS & Flags) )
  486. {
  487. if (NewSize <= 0xffff)
  488. NewSize = sizeof(HEAP_ENTRY)*((HEAP_ENTRY *)pRet-1)->Size;
  489. RtlCaptureStackBackTrace(1,
  490. 4,
  491. (PVOID *)((BYTE *)pRet+(NewSize-SPACE_STACK_ALLOC-sizeof(HEAP_ENTRY))),
  492. pLong);
  493. }
  494. return pRet;
  495. }
  496. void
  497. _declspec(naked) Prolog__RtlValidateHeap(){
  498. _asm {
  499. // this is the space for the "saved istructions"
  500. nop ;
  501. nop ;
  502. nop ;
  503. nop ;
  504. nop ;
  505. nop ;
  506. nop ;
  507. nop ;
  508. nop ;
  509. nop ;
  510. nop ;
  511. nop ;
  512. // this is the place for the JMP
  513. nop ;
  514. nop ;
  515. nop ;
  516. nop ;
  517. nop ;
  518. nop ; // dist
  519. nop ; // dist
  520. nop ; // dist
  521. nop ; // dist
  522. nop ; // dist
  523. nop ; // dist
  524. }
  525. }
  526. BOOL
  527. _I_RtlValidateHeap(
  528. HANDLE pHeap, // handle to heap block
  529. DWORD dwFlags, // heap reallocation options
  530. LPVOID lpMem // pointer to memory to validate
  531. ){
  532. ULONG * pLong = (ULONG *)_alloca(sizeof(DWORD));
  533. BOOL bRet;
  534. g_bDisableBreak = TRUE;
  535. _asm {
  536. push lpMem ;
  537. push dwFlags ;
  538. push pHeap ;
  539. call Prolog__RtlValidateHeap ;
  540. mov bRet,eax ;
  541. }
  542. g_bDisableBreak = FALSE;
  543. return bRet;
  544. }
  545. void
  546. _declspec(naked) Prolog__RtlCreateHeap(){
  547. _asm {
  548. // this is the space for the "saved istructions"
  549. nop ;
  550. nop ;
  551. nop ;
  552. nop ;
  553. nop ;
  554. nop ;
  555. nop ;
  556. nop ;
  557. nop ;
  558. nop ;
  559. nop ;
  560. nop ;
  561. // this is the place for the JMP
  562. nop ;
  563. nop ;
  564. nop ;
  565. nop ;
  566. nop ;
  567. nop ; // dist
  568. nop ; // dist
  569. nop ; // dist
  570. nop ; // dist
  571. nop ; // dist
  572. nop ; // dist
  573. nop ; // dist
  574. }
  575. }
  576. PVOID
  577. _I_RtlCreateHeap (
  578. IN ULONG Flags,
  579. IN PVOID HeapBase,
  580. IN SIZE_T ReserveSize,
  581. IN SIZE_T CommitSize,
  582. IN PVOID Lock_,
  583. IN VOID * Parameters
  584. )
  585. {
  586. EnterCriticalSection(&g_CS);
  587. ULONG * pLong = (ULONG *)_alloca(sizeof(DWORD));
  588. PVOID pHeap;
  589. _asm {
  590. push Parameters ;
  591. push Lock_ ;
  592. push CommitSize ;
  593. push ReserveSize ;
  594. push HeapBase ;
  595. push Flags ;
  596. call Prolog__RtlCreateHeap ;
  597. mov pHeap,eax ;
  598. }
  599. if (pHeap)
  600. {
  601. HEAP * pRealHeap = (HEAP *)pHeap;
  602. if (pRealHeap->Flags & (HEAP_TAIL_CHECKING_ENABLED | HEAP_FREE_CHECKING_ENABLED))
  603. {
  604. pRealHeap->Flags &= ~(HEAP_TAIL_CHECKING_ENABLED | HEAP_FREE_CHECKING_ENABLED);
  605. }
  606. if (pRealHeap->ForceFlags & (HEAP_TAIL_CHECKING_ENABLED | HEAP_FREE_CHECKING_ENABLED))
  607. {
  608. pRealHeap->ForceFlags &= ~(HEAP_TAIL_CHECKING_ENABLED | HEAP_FREE_CHECKING_ENABLED);
  609. }
  610. }
  611. //SetFinalOp(FinalOperations::ReAlloc,(ULONG_PTR)pHeap);
  612. LeaveCriticalSection(&g_CS);
  613. return pHeap;
  614. }
  615. void
  616. _declspec(naked) Prolog__RtlDestroyHeap(){
  617. _asm {
  618. // this is the space for the "saved istructions"
  619. nop ;
  620. nop ;
  621. nop ;
  622. nop ;
  623. nop ;
  624. nop ;
  625. nop ;
  626. nop ;
  627. nop ;
  628. nop ;
  629. nop ;
  630. nop ;
  631. // this is the place for the JMP
  632. nop ;
  633. nop ;
  634. nop ;
  635. nop ;
  636. nop ;
  637. nop ; // dist
  638. nop ; // dist
  639. nop ; // dist
  640. nop ; // dist
  641. nop ; // dist
  642. nop ; // dist
  643. nop ; // dist
  644. nop ; // dist
  645. }
  646. }
  647. PVOID
  648. _I_RtlDestroyHeap (
  649. IN PVOID HeapHandle
  650. )
  651. {
  652. EnterCriticalSection(&g_CS);
  653. ULONG * pLong = (ULONG *)_alloca(sizeof(DWORD));
  654. PVOID pRet;
  655. //SetFinalOp(FinalOperations::Destroy,(ULONG_PTR)HeapHandle);
  656. VALIDATE_HEAP;
  657. _asm {
  658. push HeapHandle;
  659. call Prolog__RtlDestroyHeap;
  660. mov pRet, eax;
  661. }
  662. LeaveCriticalSection(&g_CS);
  663. return pRet;
  664. }
  665. #define MAX_REMEMBER (1024)
  666. struct CSCCTrace
  667. {
  668. enum OpType {
  669. Enter = 'rtnE',
  670. Leave = 'vaeL'
  671. };
  672. OpType Type;
  673. DWORD Tid;
  674. ULONG_PTR Trace[6];
  675. } g_CSCCTrace[MAX_REMEMBER];
  676. LONG g_CSCCIndex = -1;
  677. RTL_CRITICAL_SECTION * g_HeapLock;
  678. void
  679. _declspec(naked) Prolog__RtlEnterCriticalSection(){
  680. _asm {
  681. // this is the space for the "saved istructions"
  682. nop ;
  683. nop ;
  684. nop ;
  685. nop ;
  686. nop ;
  687. nop ;
  688. nop ;
  689. nop ;
  690. nop ;
  691. nop ;
  692. nop ;
  693. nop ;
  694. // this is the place for the JMP
  695. nop ;
  696. nop ;
  697. nop ;
  698. nop ;
  699. nop ;
  700. nop ; // dist
  701. nop ; // dist
  702. nop ; // dist
  703. nop ; // dist
  704. nop ; // dist
  705. nop ; // dist
  706. nop ; // dist
  707. nop ; // dist
  708. nop ; // dist
  709. }
  710. }
  711. NTSTATUS
  712. _I_RtlEnterCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
  713. {
  714. ULONG * pLong = (ULONG * )_alloca(sizeof(ULONG ));
  715. if (g_HeapLock == CriticalSection)
  716. {
  717. long nIndex = InterlockedIncrement(&g_CSCCIndex);
  718. nIndex %= MAX_REMEMBER;
  719. CSCCTrace * pTrace = &g_CSCCTrace[nIndex];
  720. pTrace->Type = CSCCTrace::Enter;
  721. pTrace->Tid =GetCurrentThreadId();
  722. RtlCaptureStackBackTrace (2,6,(PVOID *)pTrace->Trace,pLong);
  723. }
  724. NTSTATUS Status;
  725. _asm {
  726. push CriticalSection;
  727. call Prolog__RtlEnterCriticalSection;
  728. mov Status,eax;
  729. };
  730. return Status;
  731. }
  732. void
  733. _declspec(naked) Prolog__RtlLeaveCriticalSection(){
  734. _asm {
  735. // this is the space for the "saved istructions"
  736. nop ;
  737. nop ;
  738. nop ;
  739. nop ;
  740. nop ;
  741. nop ;
  742. nop ;
  743. nop ;
  744. nop ;
  745. nop ;
  746. nop ;
  747. nop ;
  748. // this is the place for the JMP
  749. nop ;
  750. nop ;
  751. nop ;
  752. nop ;
  753. nop ;
  754. nop ; // dist
  755. nop ; // dist
  756. nop ; // dist
  757. nop ; // dist
  758. nop ; // dist
  759. nop ; // dist
  760. nop ; // dist
  761. nop ; // dist
  762. nop ; // dist
  763. nop ; // dist
  764. }
  765. }
  766. NTSTATUS
  767. _I_RtlLeaveCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
  768. {
  769. ULONG * pLong = (ULONG * )_alloca(sizeof(ULONG ));
  770. if (g_HeapLock == CriticalSection)
  771. {
  772. long nIndex = InterlockedIncrement(&g_CSCCIndex);
  773. nIndex %= MAX_REMEMBER;
  774. CSCCTrace * pTrace = &g_CSCCTrace[nIndex];
  775. pTrace->Type = CSCCTrace::Leave;
  776. pTrace->Tid =GetCurrentThreadId();
  777. RtlCaptureStackBackTrace (2,6,(PVOID *)pTrace->Trace,pLong);
  778. }
  779. NTSTATUS Status;
  780. _asm {
  781. push CriticalSection;
  782. call Prolog__RtlLeaveCriticalSection;
  783. mov Status,eax;
  784. };
  785. return Status;
  786. }
  787. void intercept2(WCHAR * Module,
  788. LPSTR Function,
  789. VOID * NewRoutine,
  790. VOID * pPrologStorage,
  791. DWORD Size)
  792. {
  793. FARPROC OldRoutine = GetProcAddress(GetModuleHandleW(Module),Function);
  794. if (OldRoutine)
  795. {
  796. MEMORY_BASIC_INFORMATION MemBI;
  797. DWORD dwOldProtect;
  798. BOOL bRet, bRet2;
  799. DWORD dwRet;
  800. dwRet = VirtualQuery(OldRoutine,&MemBI,sizeof(MemBI));
  801. bRet = VirtualProtect(MemBI.BaseAddress,
  802. MemBI.RegionSize,
  803. PAGE_EXECUTE_WRITECOPY,
  804. &dwOldProtect);
  805. dwRet = VirtualQuery(pPrologStorage,&MemBI,sizeof(MemBI));
  806. bRet2 = VirtualProtect(MemBI.BaseAddress,
  807. MemBI.RegionSize,
  808. PAGE_EXECUTE_WRITECOPY,
  809. &dwOldProtect);
  810. if (bRet && bRet2)
  811. {
  812. VOID * pToJump = (VOID *)NewRoutine;
  813. BYTE Arr[SIZE_JUMP_ADR] = { 0xe9 };
  814. LONG * pOffset = (LONG *)&Arr[1];
  815. * pOffset = (LONG)NewRoutine - (LONG)OldRoutine - SIZE_JUMP_ADR ;
  816. // save the old code
  817. memcpy(pPrologStorage,OldRoutine,Size);
  818. // put the new code
  819. memset(OldRoutine,0x90,Size);
  820. memcpy(OldRoutine,Arr,SIZE_JUMP_ADR);
  821. // adjust the prolog to continue
  822. * pOffset = (LONG)OldRoutine + Size - (LONG)pPrologStorage - SIZE_SAVED_INSTR - SIZE_JUMP_ADR; // magic for nops
  823. memcpy((BYTE *)pPrologStorage+SIZE_SAVED_INSTR,Arr,SIZE_JUMP_ADR);
  824. }
  825. }
  826. else
  827. {
  828. OutputDebugStringA("GetProcAddress FAIL\n");
  829. }
  830. }
  831. void unintercept(WCHAR * Module,
  832. LPSTR Function,
  833. VOID * pPrologStorage,
  834. DWORD Size)
  835. {
  836. FARPROC OldRoutine = GetProcAddress(GetModuleHandleW(Module),Function);
  837. if (OldRoutine)
  838. {
  839. memcpy((void *)OldRoutine,pPrologStorage,Size);
  840. }
  841. }
  842. #endif /*_X86_*/
  843. class CSetVectoredHandler
  844. {
  845. private:
  846. // static ULONG_PTR Base;
  847. // static ULONG_PTR Limit;
  848. PVOID pVectorHandler;
  849. enum ExceptionTypes
  850. {
  851. StatusAccessViolation,
  852. CXXException,
  853. StatusNoMemory,
  854. OtherExceptions,
  855. LastException
  856. };
  857. static LONG ExceptionCounters[LastException];
  858. static DWORD s_ThreadId;
  859. /*
  860. static CONTEXT s_Context;
  861. static EXCEPTION_RECORD s_ExceptionRecord;
  862. #ifdef _X86_
  863. static BYTE s_Stack[4*1024];
  864. #endif
  865. */
  866. /*
  867. BOOL GetDllLimits(WCHAR * pDllName)
  868. {
  869. UNICODE_STRING DllName;
  870. RtlInitUnicodeString(&DllName,pDllName);
  871. PEB_LDR_DATA * pLdr = NtCurrentPeb()->Ldr;
  872. LIST_ENTRY * pHeadEntry = &pLdr->InLoadOrderModuleList;
  873. LIST_ENTRY * pEntry = pLdr->InLoadOrderModuleList.Flink;
  874. BOOL bFound = FALSE;
  875. while (pHeadEntry != pEntry)
  876. {
  877. LDR_DATA_TABLE_ENTRY * pData = CONTAINING_RECORD(pEntry,
  878. LDR_DATA_TABLE_ENTRY,
  879. InLoadOrderLinks);
  880. if (0 == wbem_wcsicmp(DllName.Buffer,pData->BaseDllName.Buffer))
  881. {
  882. //OutputDebugStringA("found\n");
  883. Base = (ULONG_PTR)pData->DllBase;
  884. Limit = Base + (ULONG_PTR)pData->SizeOfImage;
  885. bFound = TRUE;
  886. break;
  887. }
  888. pEntry = pEntry->Flink;
  889. }
  890. return bFound;
  891. }
  892. */
  893. public:
  894. CSetVectoredHandler()
  895. {
  896. pVectorHandler = NULL;
  897. //if (GetDllLimits(L"fastprox.dll"))
  898. //{
  899. pVectorHandler = AddVectoredExceptionHandler(TRUE,CSetVectoredHandler::VectoredHandler);
  900. //}
  901. };
  902. ~CSetVectoredHandler()
  903. {
  904. if (pVectorHandler)
  905. RemoveVectoredExceptionHandler(pVectorHandler);
  906. };
  907. static LONG WINAPI VectoredHandler(PEXCEPTION_POINTERS ExceptionInfo)
  908. {
  909. PEXCEPTION_RECORD pExr = ExceptionInfo->ExceptionRecord;
  910. PCONTEXT pCxr = ExceptionInfo->ContextRecord;
  911. BYTE * pESP;
  912. HANDLE hThread;
  913. PRTL_CRITICAL_SECTION LoaderLockPointer;
  914. BOOL bHoldingLoaderLock;
  915. ULONG c;
  916. switch (pExr->ExceptionCode)
  917. {
  918. case STATUS_ACCESS_VIOLATION:
  919. /*
  920. s_Context = *pCxr;
  921. s_ExceptionRecord = *pExr;
  922. #ifdef _X86_
  923. pESP = (BYTE *)pCxr->Esp;
  924. pESP = (BYTE *)((ULONG_PTR)pESP&0xFFFFF000);
  925. memcpy(s_Stack,pESP,4*1024);
  926. #endif
  927. */
  928. case STATUS_PRIVILEGED_INSTRUCTION:
  929. case STATUS_INVALID_HANDLE:
  930. case STATUS_STACK_OVERFLOW:
  931. case STATUS_POSSIBLE_DEADLOCK:
  932. InterlockedIncrement(&ExceptionCounters[(LONG)StatusAccessViolation]);
  933. DebugBreak();
  934. break;
  935. case 0xe06d7363:
  936. InterlockedIncrement(&ExceptionCounters[(LONG)CXXException]);
  937. break;
  938. case STATUS_NO_MEMORY:
  939. InterlockedIncrement(&ExceptionCounters[(LONG)StatusNoMemory]);
  940. break;
  941. default:
  942. InterlockedIncrement(&ExceptionCounters[(LONG)OtherExceptions]);
  943. break;
  944. }
  945. return EXCEPTION_CONTINUE_SEARCH;
  946. }
  947. } ; //g_C;
  948. LONG CSetVectoredHandler::ExceptionCounters[CSetVectoredHandler::LastException];
  949. DWORD CSetVectoredHandler::s_ThreadId;
  950. /*
  951. CONTEXT CSetVectoredHandler::s_Context;
  952. EXCEPTION_RECORD CSetVectoredHandler::s_ExceptionRecord;
  953. #ifdef _X86_
  954. BYTE CSetVectoredHandler::s_Stack[4*1024];
  955. #endif
  956. */
  957. #endif
  958. /******************************************************************************
  959. *
  960. * Name:
  961. *
  962. *
  963. * Description:
  964. *
  965. *
  966. *****************************************************************************/
  967. #define CORE_PROVIDER_UNLOAD_TIMEOUT ( 30 * 1000 )
  968. /******************************************************************************
  969. *
  970. * Name:
  971. *
  972. *
  973. * Description:
  974. *
  975. *
  976. *****************************************************************************/
  977. HWND g_Wnd = NULL ;
  978. DWORD g_DebugLevel = 0 ;
  979. DWORD g_HostRegister = 0 ;
  980. IUnknown *g_HostClassFactory = NULL ;
  981. static const wchar_t *g_TemplateCode = L"Wmi Provider Host" ;
  982. Task_ObjectDestruction *g_Task = NULL ;
  983. Task_FreeLibraries * g_TaskFreeLib = NULL;
  984. FactoryLifeTimeThread * g_Thread = NULL;
  985. /******************************************************************************
  986. *
  987. * Name:
  988. *
  989. *
  990. * Description:
  991. *
  992. *
  993. *****************************************************************************/
  994. void initiateShutdown(void);
  995. LRESULT CALLBACK WindowsMainProc ( HWND a_hWnd , UINT a_message , WPARAM a_wParam , LPARAM a_lParam )
  996. {
  997. LRESULT t_rc = 0 ;
  998. switch ( a_message )
  999. {
  1000. case WM_DESTROY:
  1001. {
  1002. PostMessage ( a_hWnd , WM_QUIT , 0 , 0 ) ;
  1003. }
  1004. break ;
  1005. default:
  1006. {
  1007. t_rc = DefWindowProc ( a_hWnd , a_message , a_wParam , a_lParam ) ;
  1008. }
  1009. break ;
  1010. }
  1011. return ( t_rc ) ;
  1012. }
  1013. /******************************************************************************
  1014. *
  1015. * Name:
  1016. *
  1017. *
  1018. * Description:
  1019. *
  1020. *
  1021. *****************************************************************************/
  1022. HWND WindowsInit ( HINSTANCE a_HInstance )
  1023. {
  1024. WNDCLASS t_wc ;
  1025. t_wc.style = CS_HREDRAW | CS_VREDRAW ;
  1026. t_wc.lpfnWndProc = WindowsMainProc ;
  1027. t_wc.cbClsExtra = 0 ;
  1028. t_wc.cbWndExtra = 0 ;
  1029. t_wc.hInstance = a_HInstance ;
  1030. t_wc.hIcon = LoadIcon(NULL, IDI_HAND) ;
  1031. t_wc.hCursor = LoadCursor(NULL, IDC_ARROW) ;
  1032. t_wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1) ;
  1033. t_wc.lpszMenuName = NULL ;
  1034. t_wc.lpszClassName = g_TemplateCode ;
  1035. ATOM t_winClass = RegisterClass ( &t_wc ) ;
  1036. HWND t_HWnd = CreateWindow (
  1037. g_TemplateCode , // see RegisterClass() call
  1038. g_TemplateCode , // text for window title bar
  1039. WS_OVERLAPPEDWINDOW | WS_MINIMIZE , // window style
  1040. CW_USEDEFAULT , // default horizontal position
  1041. CW_USEDEFAULT , // default vertical position
  1042. CW_USEDEFAULT , // default width
  1043. CW_USEDEFAULT , // default height
  1044. NULL , // overlapped windows have no parent
  1045. NULL , // use the window class menu
  1046. a_HInstance ,
  1047. NULL // pointer not needed
  1048. ) ;
  1049. //ShowWindow ( t_HWnd , SW_SHOW ) ;
  1050. ShowWindow ( t_HWnd, SW_HIDE ) ;
  1051. UpdateWindow ( t_HWnd ) ;
  1052. HMENU t_Menu = GetSystemMenu ( t_HWnd , FALSE ) ;
  1053. if ( t_Menu )
  1054. {
  1055. DeleteMenu ( t_Menu , SC_RESTORE , MF_BYCOMMAND ) ;
  1056. }
  1057. return t_HWnd ;
  1058. }
  1059. /******************************************************************************
  1060. *
  1061. * Name:
  1062. *
  1063. *
  1064. * Description:
  1065. *
  1066. *
  1067. *****************************************************************************/
  1068. void WindowsStop ( HINSTANCE a_Instance , HWND a_HWnd )
  1069. {
  1070. DestroyWindow ( a_HWnd ) ;
  1071. UnregisterClass ( g_TemplateCode , a_Instance ) ;
  1072. }
  1073. /******************************************************************************
  1074. *
  1075. * Name:
  1076. *
  1077. *
  1078. * Description:
  1079. *
  1080. *
  1081. *****************************************************************************/
  1082. HWND WindowsStart ( HINSTANCE a_Handle )
  1083. {
  1084. HWND t_HWnd = NULL ;
  1085. if ( ! ( t_HWnd = WindowsInit ( a_Handle ) ) )
  1086. {
  1087. }
  1088. return t_HWnd ;
  1089. }
  1090. /******************************************************************************
  1091. *
  1092. * Name:
  1093. *
  1094. *
  1095. * Description:
  1096. *
  1097. *
  1098. *****************************************************************************/
  1099. void WindowsDispatch ()
  1100. {
  1101. BOOL t_GetMessage ;
  1102. MSG t_lpMsg ;
  1103. while ( ( t_GetMessage = GetMessage ( & t_lpMsg , NULL , 0 , 0 ) ) == TRUE )
  1104. {
  1105. TranslateMessage ( & t_lpMsg ) ;
  1106. DispatchMessage ( & t_lpMsg ) ;
  1107. }
  1108. }
  1109. /******************************************************************************
  1110. *
  1111. * Name:
  1112. *
  1113. *
  1114. * Description:
  1115. *
  1116. *
  1117. *****************************************************************************/
  1118. HRESULT RevokeFactories ()
  1119. {
  1120. if ( g_HostRegister )
  1121. {
  1122. CoRevokeClassObject ( g_HostRegister );
  1123. g_HostRegister = 0 ;
  1124. }
  1125. return S_OK ;
  1126. }
  1127. /******************************************************************************
  1128. *
  1129. * Name:
  1130. *
  1131. *
  1132. * Description:
  1133. *
  1134. *
  1135. *****************************************************************************/
  1136. HRESULT UninitComServer ()
  1137. {
  1138. RevokeFactories () ;
  1139. CoUninitialize () ;
  1140. return S_OK ;
  1141. }
  1142. /******************************************************************************
  1143. *
  1144. * Name:
  1145. *
  1146. *
  1147. * Description:
  1148. *
  1149. *
  1150. *****************************************************************************/
  1151. HRESULT InitComServer ( DWORD a_AuthenticationLevel , DWORD a_ImpersonationLevel )
  1152. {
  1153. HRESULT t_Result = S_OK ;
  1154. t_Result = CoInitializeEx (
  1155. 0,
  1156. COINIT_MULTITHREADED
  1157. );
  1158. if ( SUCCEEDED ( t_Result ) )
  1159. {
  1160. t_Result = CoInitializeSecurity (
  1161. NULL,
  1162. -1,
  1163. NULL,
  1164. NULL,
  1165. a_AuthenticationLevel,
  1166. a_ImpersonationLevel,
  1167. NULL,
  1168. EOAC_DYNAMIC_CLOAKING ,
  1169. 0
  1170. );
  1171. if ( FAILED ( t_Result ) )
  1172. {
  1173. CoUninitialize () ;
  1174. return t_Result ;
  1175. }
  1176. }
  1177. return t_Result ;
  1178. }
  1179. /******************************************************************************
  1180. *
  1181. * Name:
  1182. *
  1183. *
  1184. * Description:
  1185. *
  1186. *
  1187. *****************************************************************************/
  1188. HRESULT InitFactories ()
  1189. {
  1190. HRESULT t_Result = S_OK ;
  1191. DWORD t_ClassContext = CLSCTX_LOCAL_SERVER ;
  1192. DWORD t_Flags = REGCLS_SINGLEUSE ;
  1193. g_HostClassFactory = new CServerClassFactory <CServerObject_Host,_IWmiProviderHost> ;
  1194. t_Result = CoRegisterClassObject (
  1195. CLSID_WmiProviderHost,
  1196. g_HostClassFactory,
  1197. t_ClassContext,
  1198. t_Flags,
  1199. & g_HostRegister
  1200. );
  1201. if ( FAILED ( t_Result ) )
  1202. {
  1203. if ( g_HostRegister )
  1204. {
  1205. CoRevokeClassObject ( g_HostRegister );
  1206. g_HostRegister = 0 ;
  1207. g_HostClassFactory->Release () ;
  1208. g_HostClassFactory = NULL ;
  1209. }
  1210. }
  1211. return t_Result ;
  1212. }
  1213. /******************************************************************************
  1214. *
  1215. * Name:
  1216. *
  1217. *
  1218. * Description:
  1219. *
  1220. *
  1221. *****************************************************************************/
  1222. HRESULT Enqueue_ObjectDestruction ( WmiThread < ULONG > *a_Thread )
  1223. {
  1224. HRESULT t_Result = S_OK ;
  1225. g_Task = new Task_ObjectDestruction ( *ProviderSubSystem_Globals :: s_Allocator ) ;
  1226. if ( g_Task )
  1227. {
  1228. g_Task->AddRef () ;
  1229. if ( g_Task->Initialize () == e_StatusCode_Success )
  1230. {
  1231. if ( a_Thread->EnQueueAlertable ( 0 , *g_Task ) == e_StatusCode_Success )
  1232. {
  1233. }
  1234. else
  1235. {
  1236. t_Result = WBEM_E_OUT_OF_MEMORY ;
  1237. }
  1238. }
  1239. else
  1240. {
  1241. t_Result = WBEM_E_OUT_OF_MEMORY ;
  1242. }
  1243. }
  1244. else
  1245. {
  1246. t_Result = WBEM_E_OUT_OF_MEMORY ;
  1247. }
  1248. if ( FAILED ( t_Result ) )
  1249. {
  1250. g_Task = NULL ;
  1251. }
  1252. if (SUCCEEDED(t_Result))
  1253. {
  1254. g_TaskFreeLib = new Task_FreeLibraries(*ProviderSubSystem_Globals::s_Allocator);
  1255. if (g_TaskFreeLib)
  1256. {
  1257. g_TaskFreeLib->AddRef () ;
  1258. if ( g_TaskFreeLib->Initialize () == e_StatusCode_Success )
  1259. {
  1260. if (e_StatusCode_Success != a_Thread->EnQueueAlertable(0,*g_TaskFreeLib))
  1261. {
  1262. t_Result = WBEM_E_OUT_OF_MEMORY ;
  1263. }
  1264. }
  1265. else
  1266. {
  1267. t_Result = WBEM_E_OUT_OF_MEMORY ;
  1268. }
  1269. }
  1270. else
  1271. {
  1272. t_Result = WBEM_E_OUT_OF_MEMORY ;
  1273. }
  1274. }
  1275. return t_Result ;
  1276. }
  1277. /******************************************************************************
  1278. *
  1279. * Name:
  1280. *
  1281. *
  1282. * Description:
  1283. *
  1284. *
  1285. *****************************************************************************/
  1286. HRESULT Dequeue_ObjectDestruction ( WmiThread < ULONG > *a_Thread )
  1287. {
  1288. HRESULT t_Result = S_OK ;
  1289. /*
  1290. // Don't clean up since we need a guarantee that no syncronisation needs to take place
  1291. if ( g_Task )
  1292. {
  1293. g_Task->Release () ;
  1294. }
  1295. */
  1296. IUnknown * pUnk;
  1297. if (pUnk = (IUnknown *)InterlockedCompareExchangePointer((PVOID *)&g_TaskFreeLib,0,(PVOID)g_TaskFreeLib))
  1298. {
  1299. pUnk->Release();
  1300. }
  1301. return t_Result ;
  1302. }
  1303. void exitIfManaged()
  1304. {
  1305. // Clean managed heap
  1306. HINSTANCE hmod = GetModuleHandle(L"mscoree.dll");
  1307. if (hmod != NULL)
  1308. {
  1309. typedef void (WINAPI * PFN_EEShutDownCOM)();
  1310. PFN_EEShutDownCOM uninitEE = (PFN_EEShutDownCOM)GetProcAddress(hmod, "CoEEShutDownCOM");
  1311. if (uninitEE)
  1312. {
  1313. uninitEE();
  1314. }
  1315. }
  1316. // If we're part of a managed app (aka. a managed component is present in our
  1317. // process) we cannot excute any global shutdown code. In this case we are just calling
  1318. // framework shutdown.
  1319. // To determine if we're a managed app, we check if mscoree.dll is loaded.
  1320. // Then, if CorExitProcess is available, we call it.
  1321. typedef void (WINAPI * PFN_EXIT_PROCESS)(UINT uExitCode);
  1322. PFN_EXIT_PROCESS pfn;
  1323. if (hmod != NULL)
  1324. {
  1325. pfn = (PFN_EXIT_PROCESS)GetProcAddress(hmod, "CorExitProcess");
  1326. if (pfn != NULL)
  1327. {
  1328. if (ProviderSubSystem_Globals :: s_ObjectsInProgress == 0) return;
  1329. // We still have oustanding objects
  1330. // Revoke Factories and UnInit com
  1331. UninitComServer();
  1332. pfn(0);
  1333. }
  1334. }
  1335. };
  1336. /******************************************************************************
  1337. *
  1338. * Name:
  1339. *
  1340. *
  1341. * Description:
  1342. *
  1343. *
  1344. *****************************************************************************/
  1345. HRESULT Process ()
  1346. {
  1347. DWORD t_ImpersonationLevel = RPC_C_IMP_LEVEL_IMPERSONATE ;
  1348. DWORD t_AuthenticationLevel = RPC_C_AUTHN_LEVEL_CONNECT;
  1349. HRESULT t_Result = InitComServer ( t_AuthenticationLevel , t_ImpersonationLevel ) ;
  1350. if ( SUCCEEDED ( t_Result ) )
  1351. {
  1352. WmiStatusCode t_StatusCode = WmiDebugLog :: Initialize ( *ProviderSubSystem_Globals :: s_Allocator ) ;
  1353. if ( t_StatusCode == e_StatusCode_Success )
  1354. {
  1355. t_Result = ProviderSubSystem_Globals :: Initialize_SharedCounters () ;
  1356. if ( FAILED ( t_Result ) )
  1357. {
  1358. t_Result = S_OK ;
  1359. }
  1360. t_Result = ProviderSubSystem_Globals :: Initialize_Events () ;
  1361. if ( SUCCEEDED ( t_Result ) )
  1362. {
  1363. t_Result = ProviderSubSystem_Common_Globals :: CreateSystemAces () ;
  1364. }
  1365. if ( SUCCEEDED ( t_Result ) )
  1366. {
  1367. IWbemLocator *t_Locator = NULL ;
  1368. HRESULT t_Result = CoCreateInstance (
  1369. CLSID_WbemLocator ,
  1370. NULL ,
  1371. CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER ,
  1372. IID_IUnknown ,
  1373. ( void ** ) & t_Locator
  1374. );
  1375. if ( SUCCEEDED ( t_Result ) )
  1376. {
  1377. IWbemServices *t_Service = NULL ;
  1378. BSTR t_Namespace = SysAllocString ( L"Root" ) ;
  1379. if ( t_Namespace )
  1380. {
  1381. t_Result = t_Locator->ConnectServer (
  1382. t_Namespace ,
  1383. NULL ,
  1384. NULL,
  1385. NULL ,
  1386. 0 ,
  1387. NULL,
  1388. NULL,
  1389. & t_Service
  1390. ) ;
  1391. if ( SUCCEEDED ( t_Result ) )
  1392. {
  1393. CServerObject_GlobalRegistration t_Registration ;
  1394. t_Result = t_Registration.SetContext (
  1395. NULL ,
  1396. NULL ,
  1397. t_Service
  1398. ) ;
  1399. if ( SUCCEEDED ( t_Result ) )
  1400. {
  1401. t_Result = t_Registration.Load (
  1402. e_All
  1403. ) ;
  1404. if ( SUCCEEDED ( t_Result ) )
  1405. {
  1406. ProviderSubSystem_Globals :: s_StrobeTimeout = t_Registration.GetUnloadTimeoutMilliSeconds () >> 1 ;
  1407. ProviderSubSystem_Globals :: s_InternalCacheTimeout = t_Registration.GetUnloadTimeoutMilliSeconds () ;
  1408. ProviderSubSystem_Globals :: s_ObjectCacheTimeout = t_Registration.GetObjectUnloadTimeoutMilliSeconds () ;
  1409. ProviderSubSystem_Globals :: s_EventCacheTimeout = t_Registration.GetEventUnloadTimeoutMilliSeconds () ;
  1410. }
  1411. }
  1412. if ( SUCCEEDED ( t_Result ) )
  1413. {
  1414. CServerObject_HostQuotaRegistration t_Registration ;
  1415. t_Result = t_Registration.SetContext (
  1416. NULL ,
  1417. NULL ,
  1418. t_Service
  1419. ) ;
  1420. if ( SUCCEEDED ( t_Result ) )
  1421. {
  1422. t_Result = t_Registration.Load (
  1423. e_All
  1424. ) ;
  1425. if ( SUCCEEDED ( t_Result ) )
  1426. {
  1427. ProviderSubSystem_Globals ::s_Quota_ProcessLimitCount = t_Registration.GetProcessLimitAllHosts () ;
  1428. ProviderSubSystem_Globals ::s_Quota_ProcessMemoryLimitCount = t_Registration.GetMemoryPerHost () ;
  1429. ProviderSubSystem_Globals ::s_Quota_JobMemoryLimitCount = t_Registration.GetMemoryAllHosts () ;
  1430. ProviderSubSystem_Globals ::s_Quota_HandleCount = t_Registration.GetHandlesPerHost () ;
  1431. ProviderSubSystem_Globals ::s_Quota_NumberOfThreads = t_Registration.GetThreadsPerHost () ;
  1432. ProviderSubSystem_Globals ::s_Quota_PrivatePageCount = t_Registration.GetMemoryPerHost () ;
  1433. }
  1434. }
  1435. }
  1436. t_Service->Release () ;
  1437. }
  1438. SysFreeString ( t_Namespace ) ;
  1439. }
  1440. else
  1441. {
  1442. t_Result = WBEM_E_OUT_OF_MEMORY ;
  1443. }
  1444. t_Locator->Release () ;
  1445. }
  1446. }
  1447. if ( SUCCEEDED ( t_Result ) )
  1448. {
  1449. g_Thread = new FactoryLifeTimeThread ( *ProviderSubSystem_Globals :: s_Allocator , DEFAULT_PROVIDER_TIMEOUT ) ;
  1450. if ( g_Thread )
  1451. {
  1452. g_Thread->AddRef () ;
  1453. t_StatusCode = g_Thread->Initialize () ;
  1454. if ( t_StatusCode == e_StatusCode_Success )
  1455. {
  1456. t_Result = Enqueue_ObjectDestruction ( g_Thread ) ;
  1457. if ( SUCCEEDED ( t_Result ) )
  1458. {
  1459. t_Result = InitFactories () ;
  1460. #ifdef DEV_BUILD
  1461. #ifdef _X86_
  1462. // g_FaultHeapEnabled = TRUE;
  1463. // g_FaultFileEnabled = TRUE;
  1464. #endif
  1465. #endif
  1466. if ( SUCCEEDED ( t_Result ) )
  1467. {
  1468. Wmi_SetStructuredExceptionHandler t_StructuredException ;
  1469. try
  1470. {
  1471. WindowsDispatch () ;
  1472. }
  1473. catch ( Wmi_Structured_Exception t_StructuredException )
  1474. {
  1475. }
  1476. }
  1477. Dequeue_ObjectDestruction ( g_Thread ) ;
  1478. }
  1479. HANDLE t_ThreadHandle = NULL ;
  1480. BOOL t_Status = DuplicateHandle (
  1481. GetCurrentProcess () ,
  1482. g_Thread->GetHandle () ,
  1483. GetCurrentProcess () ,
  1484. & t_ThreadHandle,
  1485. 0 ,
  1486. FALSE ,
  1487. DUPLICATE_SAME_ACCESS
  1488. ) ;
  1489. g_Thread->Release () ;
  1490. WaitForSingleObject ( t_ThreadHandle , INFINITE ) ;
  1491. CloseHandle ( t_ThreadHandle ) ;
  1492. g_Thread = NULL;
  1493. Dequeue_ObjectDestruction (NULL);
  1494. }
  1495. }
  1496. else
  1497. {
  1498. t_Result = WBEM_E_OUT_OF_MEMORY ;
  1499. }
  1500. exitIfManaged();
  1501. t_Result = ProviderSubSystem_Common_Globals :: DeleteSystemAces () ;
  1502. t_Result = ProviderSubSystem_Globals :: UnInitialize_Events () ;
  1503. }
  1504. t_Result = ProviderSubSystem_Globals :: UnInitialize_SharedCounters () ;
  1505. WmiStatusCode t_StatusCode = WmiDebugLog :: UnInitialize ( *ProviderSubSystem_Globals :: s_Allocator ) ;
  1506. }
  1507. UninitComServer () ;
  1508. }
  1509. return t_Result ;
  1510. }
  1511. /******************************************************************************
  1512. *
  1513. * Name:
  1514. *
  1515. *
  1516. * Description:
  1517. *
  1518. *
  1519. *****************************************************************************/
  1520. BOOL ParseCommandLine ()
  1521. {
  1522. BOOL t_Exit = FALSE ;
  1523. LPTSTR t_CommandLine = GetCommandLineW () ;
  1524. if ( t_CommandLine )
  1525. {
  1526. wchar_t *t_Arg = NULL ;
  1527. wchar_t *t_ApplicationArg = NULL ;
  1528. t_ApplicationArg = wcstok ( t_CommandLine , L" \t") ;
  1529. t_Arg = wcstok ( NULL , L" \t" ) ;
  1530. if ( t_Arg )
  1531. {
  1532. if ( lstrcmpi ( t_Arg , L"/RegServer" ) == 0 )
  1533. {
  1534. t_Exit = TRUE ;
  1535. DllRegisterServer () ;
  1536. }
  1537. else if ( lstrcmpi ( t_Arg , L"/UnRegServer" ) == 0 )
  1538. {
  1539. t_Exit = TRUE ;
  1540. DllUnregisterServer () ;
  1541. }
  1542. }
  1543. }
  1544. return t_Exit ;
  1545. }
  1546. /******************************************************************************
  1547. *
  1548. * Name:
  1549. *
  1550. *
  1551. * Description:
  1552. *
  1553. *
  1554. *****************************************************************************/
  1555. #include <arena.h>
  1556. LONG
  1557. WINAPI
  1558. SvchostUnhandledExceptionFilter(
  1559. struct _EXCEPTION_POINTERS *ExceptionInfo
  1560. )
  1561. {
  1562. return RtlUnhandledExceptionFilter(ExceptionInfo);
  1563. }
  1564. int WINAPI WinMain (
  1565. HINSTANCE hInstance, // handle to current instance
  1566. HINSTANCE hPrevInstance, // handle to previous instance
  1567. LPSTR lpCmdLine, // pointer to command line
  1568. int nShowCmd // show state of window
  1569. )
  1570. {
  1571. #ifdef DEV_BUILD
  1572. //SetUnhandledExceptionFilter(&SvchostUnhandledExceptionFilter);
  1573. //SetErrorMode(SEM_FAILCRITICALERRORS);
  1574. #ifdef _X86_
  1575. //NtCurrentPeb()->BeingDebugged = 1;
  1576. intercept2(L"ntdll.dll","RtlFreeHeap",_I_RtlFreeHeap,Prolog__RtlFreeHeap,5);
  1577. intercept2(L"ntdll.dll","RtlAllocateHeap",_I_RtlAllocateHeap,Prolog__RtlAllocateHeap,5);
  1578. intercept2(L"ntdll.dll","RtlReAllocateHeap",_I_RtlReAllocateHeap,Prolog__RtlReAllocateHeap,5);
  1579. intercept2(L"ntdll.dll","RtlValidateHeap",_I_RtlValidateHeap,Prolog__RtlValidateHeap,7);
  1580. intercept2(L"ntdll.dll","RtlCreateHeap",_I_RtlCreateHeap,Prolog__RtlCreateHeap,5);
  1581. intercept2(L"ntdll.dll","RtlDestroyHeap",_I_RtlDestroyHeap,Prolog__RtlDestroyHeap,6);
  1582. //intercept2(L"ntdll.dll","RtlEnterCriticalSection",_I_RtlEnterCriticalSection,Prolog__RtlEnterCriticalSection,7);
  1583. //intercept2(L"ntdll.dll","RtlLeaveCriticalSection",_I_RtlLeaveCriticalSection,Prolog__RtlLeaveCriticalSection,6);
  1584. intercept2(L"kernel32.dll","CreateEventW",_I_CreateEvent,Prolog__CreateEvent,6);
  1585. intercept2(L"kernel32.dll","WriteFile",_I_WriteFile,Prolog__WriteFile,7);
  1586. intercept2(L"kernel32.dll","ReadFile",_I_ReadFile,Prolog__ReadFile,7);
  1587. HANDLE hHeap = CWin32DefaultArena::GetArenaHeap();
  1588. g_HeapLock = *((RTL_CRITICAL_SECTION **)((BYTE *)hHeap+0x578));
  1589. // this is for CritSec timeout
  1590. //LARGE_INTEGER * pLi = (LARGE_INTEGER *)0x77fC47E8;
  1591. //pLi->QuadPart = 0xffffffffdc3cba00; // 2 min
  1592. //pLi->QuadPart = 0xfffffffff4143e00; // 2 sec
  1593. #endif /*_X86_*/
  1594. #endif
  1595. setlocale(LC_CTYPE,"English");
  1596. HRESULT t_Result = ProviderSubSystem_Globals :: Global_Startup () ;
  1597. if ( SUCCEEDED ( t_Result ) )
  1598. {
  1599. BOOL t_Exit = ParseCommandLine () ;
  1600. if ( ! t_Exit )
  1601. {
  1602. RPC_STATUS t_Status = RpcMgmtSetServerStackSize ( ProviderSubSystem_Common_Globals :: GetDefaultStackSize () );
  1603. g_Wnd = WindowsStart ( hInstance ) ;
  1604. t_Result = Process () ;
  1605. WindowsStop ( hInstance , g_Wnd ) ;
  1606. }
  1607. t_Result = ProviderSubSystem_Globals :: Global_Shutdown () ;
  1608. }
  1609. #ifdef DEV_BUILD
  1610. #ifdef _X86_
  1611. //VALIDATE_HEAP;
  1612. unintercept(L"ntdll.dll","RtlFreeHeap",Prolog__RtlFreeHeap,5);
  1613. unintercept(L"ntdll.dll","RtlAllocateHeap",Prolog__RtlAllocateHeap,5);
  1614. unintercept(L"ntdll.dll","RtlReAllocateHeap",Prolog__RtlReAllocateHeap,5);
  1615. unintercept(L"ntdll.dll","RtlValidateHeap",Prolog__RtlValidateHeap,7);
  1616. unintercept(L"ntdll.dll","RtlCreateHeap",Prolog__RtlCreateHeap,5);
  1617. unintercept(L"ntdll.dll","RtlDestroyHeap",Prolog__RtlDestroyHeap,6);
  1618. //unintercept(L"ntdll.dll","RtlEnterCriticalSection",Prolog__RtlEnterCriticalSection,7);
  1619. //unintercept(L"ntdll.dll","RtlLeaveCriticalSection",Prolog__RtlLeaveCriticalSection,6);
  1620. unintercept(L"kernel32.dll","CreateEventW",Prolog__CreateEvent,6);
  1621. unintercept(L"kernel32.dll","WriteFile",Prolog__WriteFile,7);
  1622. unintercept(L"kernel32.dll","ReadFile",Prolog__ReadFile,7);
  1623. #endif /*_X86_*/
  1624. #endif
  1625. return 0 ;
  1626. }
  1627. /******************************************************************************
  1628. *
  1629. * Name:
  1630. *
  1631. *
  1632. * Description:
  1633. *
  1634. *
  1635. *****************************************************************************/
  1636. WmiStatusCode FactoryLifeTimeThread :: Initialize_Callback ()
  1637. {
  1638. return e_StatusCode_Success ;
  1639. }
  1640. /******************************************************************************
  1641. *
  1642. * Name:
  1643. *
  1644. *
  1645. * Description:
  1646. *
  1647. *
  1648. *****************************************************************************/
  1649. WmiStatusCode FactoryLifeTimeThread :: UnInitialize_Callback ()
  1650. {
  1651. return e_StatusCode_Success ;
  1652. }
  1653. /******************************************************************************
  1654. *
  1655. * Name:
  1656. *
  1657. *
  1658. * Description:
  1659. *
  1660. *
  1661. *****************************************************************************/
  1662. FactoryLifeTimeThread :: FactoryLifeTimeThread (
  1663. WmiAllocator &a_Allocator ,
  1664. const ULONG &a_Timeout
  1665. ) : WmiThread < ULONG > ( a_Allocator , NULL , a_Timeout ) ,
  1666. m_Allocator ( a_Allocator )
  1667. {
  1668. }
  1669. /******************************************************************************
  1670. *
  1671. * Name:
  1672. *
  1673. *
  1674. * Description:
  1675. *
  1676. *
  1677. *****************************************************************************/
  1678. FactoryLifeTimeThread::~FactoryLifeTimeThread ()
  1679. {
  1680. }
  1681. /******************************************************************************
  1682. *
  1683. * Name:
  1684. *
  1685. *
  1686. * Description:
  1687. *
  1688. *
  1689. *****************************************************************************/
  1690. BOOL FactoryLifeTimeThread :: QuotaCheck ()
  1691. {
  1692. DWORD t_ProcessInformationSize = sizeof ( SYSTEM_PROCESS_INFORMATION ) ;
  1693. SYSTEM_PROCESS_INFORMATION *t_ProcessInformation = ( SYSTEM_PROCESS_INFORMATION * ) new BYTE [t_ProcessInformationSize] ;
  1694. if ( t_ProcessInformation )
  1695. {
  1696. BOOL t_Retry = TRUE ;
  1697. while ( t_Retry )
  1698. {
  1699. NTSTATUS t_Status = NtQuerySystemInformation (
  1700. SystemProcessInformation,
  1701. t_ProcessInformation,
  1702. t_ProcessInformationSize,
  1703. NULL
  1704. ) ;
  1705. if ( t_Status == STATUS_INFO_LENGTH_MISMATCH )
  1706. {
  1707. delete [] t_ProcessInformation;
  1708. t_ProcessInformation = NULL ;
  1709. t_ProcessInformationSize += 32768 ;
  1710. t_ProcessInformation = ( SYSTEM_PROCESS_INFORMATION * ) new BYTE [t_ProcessInformationSize] ;
  1711. if ( ! t_ProcessInformation )
  1712. {
  1713. return FALSE ;
  1714. }
  1715. }
  1716. else
  1717. {
  1718. t_Retry = FALSE ;
  1719. if ( ! NT_SUCCESS ( t_Status ) )
  1720. {
  1721. delete [] t_ProcessInformation;
  1722. t_ProcessInformation = NULL ;
  1723. return FALSE ;
  1724. }
  1725. }
  1726. }
  1727. }
  1728. else
  1729. {
  1730. return FALSE ;
  1731. }
  1732. BOOL t_Status = TRUE ;
  1733. SYSTEM_PROCESS_INFORMATION *t_Block = t_ProcessInformation ;
  1734. while ( t_Block )
  1735. {
  1736. if ( ( HandleToUlong ( t_Block->UniqueProcessId ) ) == GetCurrentProcessId () )
  1737. {
  1738. if ( t_Block->HandleCount > ProviderSubSystem_Globals::s_Quota_HandleCount )
  1739. {
  1740. DBG_PRINTFA((pBuff,"HandleCount %x %x\n",t_Block->HandleCount,ProviderSubSystem_Globals::s_Quota_HandleCount));
  1741. t_Status = FALSE ;
  1742. }
  1743. if ( t_Block->NumberOfThreads > ProviderSubSystem_Globals::s_Quota_NumberOfThreads )
  1744. {
  1745. DBG_PRINTFA((pBuff,"NumberOfThreads %x %x\n",t_Block->NumberOfThreads,ProviderSubSystem_Globals::s_Quota_NumberOfThreads));
  1746. t_Status = FALSE ;
  1747. }
  1748. if ( t_Block->PrivatePageCount > ProviderSubSystem_Globals :: s_Quota_PrivatePageCount )
  1749. {
  1750. DBG_PRINTFA((pBuff,"PrivatePageCount %x %x\n", t_Block->PrivatePageCount,ProviderSubSystem_Globals::s_Quota_PrivatePageCount));
  1751. t_Status = FALSE ;
  1752. }
  1753. }
  1754. DWORD t_NextOffSet = t_Block->NextEntryOffset ;
  1755. if ( t_NextOffSet )
  1756. {
  1757. t_Block = ( SYSTEM_PROCESS_INFORMATION * ) ( ( ( BYTE * ) t_Block ) + t_NextOffSet ) ;
  1758. }
  1759. else
  1760. {
  1761. t_Block = NULL ;
  1762. }
  1763. }
  1764. delete [] t_ProcessInformation;
  1765. return t_Status ;
  1766. }
  1767. /******************************************************************************
  1768. *
  1769. * Name:
  1770. *
  1771. *
  1772. * Description:
  1773. *
  1774. *
  1775. *****************************************************************************/
  1776. WmiStatusCode FactoryLifeTimeThread :: TimedOut ()
  1777. {
  1778. try
  1779. {
  1780. if ( QuotaCheck () == TRUE )
  1781. {
  1782. initiateShutdown();
  1783. }
  1784. else
  1785. {
  1786. CWbemGlobal_IWbemSyncProviderController *t_SyncProviderController = ProviderSubSystem_Globals :: GetSyncProviderController () ;
  1787. CWbemGlobal_IWbemSyncProvider_Container *t_Container = NULL ;
  1788. WmiStatusCode t_StatusCode = t_SyncProviderController->GetContainer ( t_Container ) ;
  1789. t_SyncProviderController->Lock () ;
  1790. _IWmiProviderQuota **t_QuotaElements = new _IWmiProviderQuota * [ t_Container->Size () ] ;
  1791. if ( t_QuotaElements )
  1792. {
  1793. CWbemGlobal_IWbemSyncProvider_Container_Iterator t_Iterator = t_Container->Begin () ;
  1794. ULONG t_Count = 0 ;
  1795. while ( ! t_Iterator.Null () )
  1796. {
  1797. SyncProviderContainerElement *t_Element = t_Iterator.GetElement () ;
  1798. t_QuotaElements [ t_Count ] = NULL ;
  1799. HRESULT t_Result = t_Element->QueryInterface ( IID__IWmiProviderQuota , ( void ** ) & t_QuotaElements [ t_Count ] ) ;
  1800. t_Iterator.Increment () ;
  1801. t_Count ++ ;
  1802. }
  1803. t_SyncProviderController->UnLock () ;
  1804. for ( ULONG t_Index = 0 ; t_Index < t_Count ; t_Index ++ )
  1805. {
  1806. if ( t_QuotaElements [ t_Index ] )
  1807. {
  1808. HRESULT t_Result = t_QuotaElements [ t_Index ]->Violation ( 0 , NULL , NULL ) ;
  1809. t_QuotaElements [ t_Index ]->Release () ;
  1810. }
  1811. }
  1812. delete [] t_QuotaElements ;
  1813. }
  1814. else
  1815. {
  1816. t_SyncProviderController->UnLock () ;
  1817. }
  1818. RevokeFactories () ;
  1819. /*
  1820. * Just exit since we can't safely wait for clients to disconnect correctly before cleaning up dependant resources.
  1821. */
  1822. #ifdef _X86_
  1823. #ifdef DEV_BUILD
  1824. // g_ExitProcessCalled = TRUE;
  1825. EnterCriticalSection(&g_CS);
  1826. VALIDATE_HEAP;
  1827. LeaveCriticalSection(&g_CS);
  1828. #endif
  1829. #endif
  1830. TerminateProcess ( GetCurrentProcess () , WBEM_E_QUOTA_VIOLATION ) ;
  1831. }
  1832. CoFreeUnusedLibrariesEx ( CORE_PROVIDER_UNLOAD_TIMEOUT , 0 ) ;
  1833. }
  1834. catch ( ... )
  1835. {
  1836. }
  1837. return e_StatusCode_Success ;
  1838. }
  1839. /******************************************************************************
  1840. *
  1841. * Name:
  1842. *
  1843. *
  1844. * Description:
  1845. *
  1846. *
  1847. *****************************************************************************/
  1848. void SetObjectDestruction ()
  1849. {
  1850. if ( g_Task )
  1851. {
  1852. SetEvent ( g_Task->GetEvent () ) ;
  1853. }
  1854. }
  1855. /******************************************************************************
  1856. *
  1857. * Name:
  1858. *
  1859. *
  1860. * Description:
  1861. *
  1862. *
  1863. *****************************************************************************/
  1864. WmiStatusCode Task_ObjectDestruction :: Process ( WmiThread <ULONG> &a_Thread )
  1865. {
  1866. initiateShutdown();
  1867. return e_StatusCode_EnQueue ;
  1868. }
  1869. void initiateShutdown(void)
  1870. {
  1871. if ( ProviderSubSystem_Globals :: s_CServerObject_Host_ObjectsInProgress == 0 )
  1872. {
  1873. RevokeFactories () ;
  1874. }
  1875. if (ProviderSubSystem_Globals :: s_CServerObject_StaThread_ObjectsInProgress == 0 &&
  1876. ProviderSubSystem_Globals :: s_CServerObject_Host_ObjectsInProgress == 0 )
  1877. {
  1878. CoFreeUnusedLibrariesEx(0,0);
  1879. CoFreeUnusedLibrariesEx(0,0);
  1880. PostMessage ( g_Wnd , WM_QUIT , 0 , 0 ) ;
  1881. }
  1882. };
  1883. void SetProviderDestruction()
  1884. {
  1885. if (g_TaskFreeLib) SetEvent (g_TaskFreeLib->GetEvent ());
  1886. }
  1887. WmiStatusCode Task_FreeLibraries::Process(WmiThread<ULONG> & a_Thread)
  1888. {
  1889. CoFreeUnusedLibrariesEx(PROVIDER_HOST_DLL_TIMEOUT,0);
  1890. return e_StatusCode_EnQueue ;
  1891. }