stub.c
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 8k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. /*
  2.  * stub.c - Stub ADT module.
  3.  */
  4. /* Headers
  5.  **********/
  6. #include "project.h"
  7. #pragma hdrstop
  8. #include "stub.h"
  9. /* Macros
  10.  *********/
  11. /* get a pointer to the stub type descriptor for a STUB */
  12. #define GetStubTypeDescriptor(pcs)     (&(Mrgcstd[pcs->st]))
  13. /* Types
  14.  ********/
  15. /* stub functions */
  16. typedef TWINRESULT (*UNLINKSTUBPROC)(PSTUB);
  17. typedef void (*DESTROYSTUBPROC)(PSTUB);
  18. typedef void (*LOCKSTUBPROC)(PSTUB);
  19. typedef void (*UNLOCKSTUBPROC)(PSTUB);
  20. /* stub type descriptor */
  21. typedef struct _stubtypedescriptor
  22. {
  23.    UNLINKSTUBPROC UnlinkStub;
  24.    DESTROYSTUBPROC DestroyStub;
  25.    LOCKSTUBPROC LockStub;
  26.    UNLOCKSTUBPROC UnlockStub;
  27. }
  28. STUBTYPEDESCRIPTOR;
  29. DECLARE_STANDARD_TYPES(STUBTYPEDESCRIPTOR);
  30. /* Module Prototypes
  31.  ********************/
  32. PRIVATE_CODE void LockSingleStub(PSTUB);
  33. PRIVATE_CODE void UnlockSingleStub(PSTUB);
  34. #if defined(DEBUG) || defined(VSTF)
  35. PRIVATE_CODE BOOL IsValidStubType(STUBTYPE);
  36. #endif
  37. #ifdef DEBUG
  38. PRIVATE_CODE LPCTSTR GetStubName(PCSTUB);
  39. #endif
  40. /* Module Variables
  41.  *******************/
  42. #pragma data_seg(DATA_SEG_READ_ONLY)
  43. /* stub type descriptors */
  44. /* Cast off compiler complaints about pointer argument mismatch. */
  45. PRIVATE_DATA CONST STUBTYPEDESCRIPTOR Mrgcstd[] =
  46. {
  47.    /* object twin STUB descriptor */
  48.    {
  49.       (UNLINKSTUBPROC)UnlinkObjectTwin,
  50.       (DESTROYSTUBPROC)DestroyObjectTwin,
  51.       LockSingleStub,
  52.       UnlockSingleStub
  53.    },
  54.    /* twin family STUB descriptor */
  55.    {
  56.       (UNLINKSTUBPROC)UnlinkTwinFamily,
  57.       (DESTROYSTUBPROC)DestroyTwinFamily,
  58.       LockSingleStub,
  59.       UnlockSingleStub
  60.    },
  61.    /* folder pair STUB descriptor */
  62.    {
  63.       (UNLINKSTUBPROC)UnlinkFolderPair,
  64.       (DESTROYSTUBPROC)DestroyFolderPair,
  65.       (LOCKSTUBPROC)LockFolderPair,
  66.       (UNLOCKSTUBPROC)UnlockFolderPair
  67.    }
  68. };
  69. #pragma data_seg()
  70. /***************************** Private Functions *****************************/
  71. /*
  72. ** LockSingleStub()
  73. **
  74. **
  75. **
  76. ** Arguments:
  77. **
  78. ** Returns:
  79. **
  80. ** Side Effects:  none
  81. */
  82. PRIVATE_CODE void LockSingleStub(PSTUB ps)
  83. {
  84.    ASSERT(IS_VALID_STRUCT_PTR(ps, CSTUB));
  85.    ASSERT(IsStubFlagClear(ps, STUB_FL_UNLINKED));
  86.    ASSERT(ps->ulcLock < ULONG_MAX);
  87.    ps->ulcLock++;
  88.    return;
  89. }
  90. /*
  91. ** UnlockSingleStub()
  92. **
  93. **
  94. **
  95. ** Arguments:
  96. **
  97. ** Returns:
  98. **
  99. ** Side Effects:  none
  100. */
  101. PRIVATE_CODE void UnlockSingleStub(PSTUB ps)
  102. {
  103.    ASSERT(IS_VALID_STRUCT_PTR(ps, CSTUB));
  104.    if (EVAL(ps->ulcLock > 0))
  105.    {
  106.       ps->ulcLock--;
  107.       if (! ps->ulcLock &&
  108.           IsStubFlagSet(ps, STUB_FL_UNLINKED))
  109.          DestroyStub(ps);
  110.    }
  111.    return;
  112. }
  113. #if defined(DEBUG) || defined(VSTF)
  114. /*
  115. ** IsValidStubType()
  116. **
  117. **
  118. **
  119. ** Arguments:
  120. **
  121. ** Returns:
  122. **
  123. ** Side Effects:  none
  124. */
  125. PRIVATE_CODE BOOL IsValidStubType(STUBTYPE st)
  126. {
  127.    BOOL bResult;
  128.    switch (st)
  129.    {
  130.       case ST_OBJECTTWIN:
  131.       case ST_TWINFAMILY:
  132.       case ST_FOLDERPAIR:
  133.          bResult = TRUE;
  134.          break;
  135.       default:
  136.          bResult = FALSE;
  137.          ERROR_OUT((TEXT("IsValidStubType(): Invalid STUB type %d."),
  138.                     st));
  139.    }
  140.    return(bResult);
  141. }
  142. #endif
  143. #ifdef DEBUG
  144. /*
  145. ** GetStubName()
  146. **
  147. **
  148. **
  149. ** Arguments:
  150. **
  151. ** Returns:       TWINRESULT
  152. **
  153. ** Side Effects:  none
  154. */
  155. PRIVATE_CODE LPCTSTR GetStubName(PCSTUB pcs)
  156. {
  157.    LPCTSTR pcszStubName;
  158.    ASSERT(IS_VALID_STRUCT_PTR(pcs, CSTUB));
  159.    switch (pcs->st)
  160.    {
  161.       case ST_OBJECTTWIN:
  162.          pcszStubName = TEXT("object twin");
  163.          break;
  164.       case ST_TWINFAMILY:
  165.          pcszStubName = TEXT("twin family");
  166.          break;
  167.       case ST_FOLDERPAIR:
  168.          pcszStubName = TEXT("folder twin");
  169.          break;
  170.       default:
  171.          ERROR_OUT((TEXT("GetStubName() called on unrecognized stub type %d."),
  172.                     pcs->st));
  173.          pcszStubName = TEXT("UNKNOWN");
  174.          break;
  175.    }
  176.    ASSERT(IS_VALID_STRING_PTR(pcszStubName, CSTR));
  177.    return(pcszStubName);
  178. }
  179. #endif
  180. /****************************** Public Functions *****************************/
  181. /*
  182. ** InitStub()
  183. **
  184. ** Initializes a stub.
  185. **
  186. ** Arguments:     ps - pointer to stub to be initialized
  187. **                st - type of stub
  188. **
  189. ** Returns:       void
  190. **
  191. ** Side Effects:  none
  192. */
  193. PUBLIC_CODE void InitStub(PSTUB ps, STUBTYPE st)
  194. {
  195.    ASSERT(IS_VALID_WRITE_PTR(ps, STUB));
  196.    ASSERT(IsValidStubType(st));
  197.    ps->st = st;
  198.    ps->ulcLock = 0;
  199.    ps->dwFlags = 0;
  200.    ASSERT(IS_VALID_STRUCT_PTR(ps, CSTUB));
  201.    return;
  202. }
  203. /*
  204. ** DestroyStub()
  205. **
  206. ** Destroys a stub.
  207. **
  208. ** Arguments:     ps - pointer to stub to be destroyed
  209. **
  210. ** Returns:       TWINRESULT
  211. **
  212. ** Side Effects:  Depends upon stub type.
  213. */
  214. PUBLIC_CODE TWINRESULT DestroyStub(PSTUB ps)
  215. {
  216.    TWINRESULT tr;
  217.    PCSTUBTYPEDESCRIPTOR pcstd;
  218.    ASSERT(IS_VALID_STRUCT_PTR(ps, CSTUB));
  219. #ifdef DEBUG
  220.    if (IsStubFlagSet(ps, STUB_FL_UNLINKED) &&
  221.        ps->ulcLock > 0)
  222.       WARNING_OUT((TEXT("DestroyStub() called on unlinked locked %s stub %#lx."),
  223.                    GetStubName(ps),
  224.                    ps));
  225. #endif
  226.    pcstd = GetStubTypeDescriptor(ps);
  227.    /* Is the stub already unlinked? */
  228.    if (IsStubFlagSet(ps, STUB_FL_UNLINKED))
  229.       /* Yes. */
  230.       tr = TR_SUCCESS;
  231.    else
  232.       /* No.  Unlink it. */
  233.       tr = (*(pcstd->UnlinkStub))(ps);
  234.    /* Is the stub still locked? */
  235.    if (tr == TR_SUCCESS && ! ps->ulcLock)
  236.       /* No.  Wipe it out. */
  237.       (*(pcstd->DestroyStub))(ps);
  238.    return(tr);
  239. }
  240. /*
  241. ** LockStub()
  242. **
  243. **
  244. **
  245. ** Arguments:
  246. **
  247. ** Returns:
  248. **
  249. ** Side Effects:  none
  250. */
  251. PUBLIC_CODE void LockStub(PSTUB ps)
  252. {
  253.    ASSERT(IS_VALID_STRUCT_PTR(ps, CSTUB));
  254.    (*(GetStubTypeDescriptor(ps)->LockStub))(ps);
  255.    return;
  256. }
  257. /*
  258. ** UnlockStub()
  259. **
  260. ** Unlocks a stub.  Carries out any pending deletion on the stub.
  261. **
  262. ** Arguments:     ps - pointer to stub to be unlocked
  263. **
  264. ** Returns:       void
  265. **
  266. ** Side Effects:  If the stub is unlinked and the lock count decreases to 0
  267. **                after unlocking, the stub is deleted.
  268. */
  269. PUBLIC_CODE void UnlockStub(PSTUB ps)
  270. {
  271.    ASSERT(IS_VALID_STRUCT_PTR(ps, CSTUB));
  272.    (*(GetStubTypeDescriptor(ps)->UnlockStub))(ps);
  273.    return;
  274. }
  275. /*
  276. ** GetStubFlags()
  277. **
  278. **
  279. **
  280. ** Arguments:
  281. **
  282. ** Returns:
  283. **
  284. ** Side Effects:  none
  285. */
  286. PUBLIC_CODE DWORD GetStubFlags(PCSTUB pcs)
  287. {
  288.    ASSERT(IS_VALID_STRUCT_PTR(pcs, CSTUB));
  289.    return(pcs->dwFlags);
  290. }
  291. /*
  292. ** SetStubFlag()
  293. **
  294. ** Sets given flag in a stub.  Other flags in stub are not affected.
  295. **
  296. ** Arguments:     ps - pointer to stub whose flags are to be set
  297. **
  298. ** Returns:       void
  299. **
  300. ** Side Effects:  none
  301. */
  302. PUBLIC_CODE void SetStubFlag(PSTUB ps, DWORD dwFlags)
  303. {
  304.    ASSERT(IS_VALID_STRUCT_PTR(ps, CSTUB));
  305.    ASSERT(FLAGS_ARE_VALID(dwFlags, ALL_STUB_FLAGS));
  306.    SET_FLAG(ps->dwFlags, dwFlags);
  307.    return;
  308. }
  309. /*
  310. ** ClearStubFlag()
  311. **
  312. ** Clears given flag in a stub.  Other flags in stub are not affected.
  313. **
  314. ** Arguments:     ps - pointer to stub whose flags are to be set
  315. **
  316. ** Returns:       void
  317. **
  318. ** Side Effects:  none
  319. */
  320. PUBLIC_CODE void ClearStubFlag(PSTUB ps, DWORD dwFlags)
  321. {
  322.    ASSERT(IS_VALID_STRUCT_PTR(ps, CSTUB));
  323.    ASSERT(FLAGS_ARE_VALID(dwFlags, ALL_STUB_FLAGS));
  324.    CLEAR_FLAG(ps->dwFlags, dwFlags);
  325.    return;
  326. }
  327. /*
  328. ** IsStubFlagSet()
  329. **
  330. **
  331. **
  332. ** Arguments:
  333. **
  334. ** Returns:
  335. **
  336. ** Side Effects:  none
  337. */
  338. PUBLIC_CODE BOOL IsStubFlagSet(PCSTUB pcs, DWORD dwFlags)
  339. {
  340.    ASSERT(IS_VALID_STRUCT_PTR(pcs, CSTUB));
  341.    ASSERT(FLAGS_ARE_VALID(dwFlags, ALL_STUB_FLAGS));
  342.    return(IS_FLAG_SET(pcs->dwFlags, dwFlags));
  343. }
  344. /*
  345. ** IsStubFlagClear()
  346. **
  347. **
  348. **
  349. ** Arguments:
  350. **
  351. ** Returns:
  352. **
  353. ** Side Effects:  none
  354. */
  355. PUBLIC_CODE BOOL IsStubFlagClear(PCSTUB pcs, DWORD dwFlags)
  356. {
  357.    ASSERT(IS_VALID_STRUCT_PTR(pcs, CSTUB));
  358.    ASSERT(FLAGS_ARE_VALID(dwFlags, ALL_STUB_FLAGS));
  359.    return(IS_FLAG_CLEAR(pcs->dwFlags, dwFlags));
  360. }
  361. #ifdef VSTF
  362. /*
  363. ** IsValidPCSTUB()
  364. **
  365. **
  366. **
  367. ** Arguments:
  368. **
  369. ** Returns:
  370. **
  371. ** Side Effects:  none
  372. */
  373. PUBLIC_CODE BOOL IsValidPCSTUB(PCSTUB pcs)
  374. {
  375.    BOOL bResult;
  376.    if (IS_VALID_READ_PTR(pcs, CSTUB) &&
  377.        IsValidStubType(pcs->st) &&
  378.        FLAGS_ARE_VALID(pcs->dwFlags, ALL_STUB_FLAGS))
  379.       bResult = TRUE;
  380.    else
  381.       bResult = FALSE;
  382.    return(bResult);
  383. }
  384. #endif