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.

713 lines
18 KiB

  1. /*****************************************************************************
  2. *
  3. * Pidi.h
  4. *
  5. * Copyright (c) 1999 Microsoft Corporation. All Rights Reserved.
  6. *
  7. * Abstract:
  8. *
  9. * Internal header for PID driver.
  10. *
  11. *****************************************************************************/
  12. #define hresLe(le) MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, (USHORT)(le))
  13. #define HidP_Max (HidP_Feature+1)
  14. #define REGSTR_PATH_VID_PID_TEMPLATE REGSTR_PATH_JOYOEM TEXT("\\VID_%04X&PID_%04X")
  15. #define REGSTR_OEM_FF_TEMPLATE REGSTR_PATH_VID_PID_TEMPLATE TEXT("\\OEMForceFeedback")
  16. #define REGSTR_EFFECTS TEXT("Effects")
  17. #define REGSTR_ATTRIBUTES TEXT("Attributes")
  18. #define REGSTR_CLSID TEXT("CLSID")
  19. #define REGSTR_CREATEDBY TEXT("CreatedBy")
  20. #define MAX_DEVICEINTERFACE (1024)
  21. #define PIDMAKEUSAGEDWORD(Usage) \
  22. DIMAKEUSAGEDWORD(HID_USAGE_PAGE_PID, HID_USAGE_PID_##Usage )
  23. #define DIGETUSAGEPAGE(UsageAndUsagePage) ((USAGE)(HIWORD(UsageAndUsagePage)))
  24. #define DIGETUSAGE( UsageAndUsagePage) ((USAGE)(LOWORD(UsageAndUsagePage)))
  25. #define MAKE_PIDUSAGE( Usage, Offset ) { PIDMAKEUSAGEDWORD(Usage), Offset }
  26. #define MAKE_HIDUSAGE( UsagePage, Usage, Offset ) { DIMAKEUSAGEDWORD(HID_USAGE_PAGE_##UsagePage, Usage), Offset }
  27. #define PID_DIES_START (0x80000000)
  28. #define PID_DIES_STOP (0x40000000)
  29. #define PIDALLOC_INIT (0xF)
  30. #define HID_VALUE (0x01)
  31. #define HID_BUTTON (0x02)
  32. #define HID_COLLECTION (0x04)
  33. #define MAX_ORDINALS (8)
  34. #define MAX_BUTTONS (0xff)
  35. #define MAX_AXES (8)
  36. /*
  37. * Device-specific errors for USB/PID force feedback devices.
  38. */
  39. /*
  40. * The requested usage was not found.
  41. */
  42. #define DIERR_PID_USAGENOTFOUND DIERR_DRIVERFIRST + 1
  43. /*
  44. * The parameter block couldn't be downloaded to the device.
  45. */
  46. #define DIERR_PID_BLOCKLOADERROR DIERR_DRIVERFIRST + 2
  47. /*
  48. * PID initialization failed.
  49. */
  50. #define DIERR_PID_NOTINITIALIZED DIERR_DRIVERFIRST + 3
  51. /*
  52. * The provided values couldn't be scaled.
  53. */
  54. #define DIERR_PID_INVALIDSCALING DIERR_DRIVERFIRST + 4
  55. typedef CONST GUID *LPCGUID;
  56. #ifndef MAXULONG_PTR
  57. typedef DWORD ULONG_PTR;
  58. typedef DWORD *PULONG_PTR;
  59. typedef DWORD UINT_PTR;
  60. typedef DWORD *PULONG_PTR;
  61. #endif //MAXULONG_PTR
  62. /*****************************************************************************
  63. *
  64. * For each active unit, one of these structures exists to keep
  65. * track of which effects are "in use".
  66. *
  67. * Our imaginary hardware does not do dynamic memory allocation;
  68. * there are merely 16 "slots", and each "slot" can be "in use"
  69. * or "free".
  70. *
  71. *****************************************************************************/
  72. #define MAX_UNITS 4
  73. #define GLOBAL_EFFECT_MEMSZ ( 1024 )
  74. typedef struct _PIDMEM{
  75. ULONG uOfSz;
  76. INT_PTR iNext;
  77. } PIDMEM, *PPIDMEM;
  78. #define PIDMEM_OFFSET(pMem) ( HIWORD(pMem->uOfSz) )
  79. #define PIDMEM_SIZE(pMem) ( LOWORD(pMem->uOfSz) )
  80. #define PIDMEM_OFSZ(Offset, Size) ( MAKELONG((Size), (Offset)) )
  81. #define GET_NEXTOFFSET(pMem) ( PIDMEM_OFFSET(pMem) + PIDMEM_SIZE(pMem) )
  82. typedef struct _EFFECTSTATE{
  83. ULONG lEfState;
  84. PIDMEM PidMem[];
  85. } EFFECTSTATE, *PEFFECTSTATE;
  86. typedef struct _UNITSTATE {
  87. GUID GuidInstance;
  88. USHORT cEfDownloaded;
  89. USHORT nAlloc;
  90. USHORT cbAlloc;
  91. PIDMEM Guard[2];
  92. UCHAR State[GLOBAL_EFFECT_MEMSZ];
  93. } UNITSTATE, *PUNITSTATE;
  94. /*****************************************************************************
  95. *
  96. * Since the information to track each unit is so small, we pack them
  97. * together into a single shared memory block to save memory.
  98. *
  99. * We use our own GUID as the name of the memory block to avoid
  100. * collisions with other named memory blocks.
  101. *
  102. *****************************************************************************/
  103. typedef struct SHAREDMEMORY {
  104. UNITSTATE rgus[MAX_UNITS];
  105. } SHAREDMEMORY, *PSHAREDMEMORY;
  106. typedef struct _REPORTPOOL
  107. {
  108. ULONG uRamPoolSz;
  109. ULONG uRomPoolSz;
  110. ULONG uRomETCount;
  111. ULONG uSimulEfMax;
  112. ULONG uPoolAlign;
  113. } REPORTPOOL, *PREPORTPOOL;
  114. typedef struct _SZPOOL
  115. {
  116. ULONG uSzEffect;
  117. ULONG uSzEnvelope;
  118. ULONG uSzCondition;
  119. ULONG uSzCustom;
  120. ULONG uSzPeriodic;
  121. ULONG uSzConstant;
  122. ULONG uSzRamp;
  123. ULONG uSzCustomData;
  124. } SZPOOL, *PSZPOOL;
  125. typedef struct _DIUSAGEANDINST
  126. {
  127. DWORD dwUsage;
  128. DWORD dwType;
  129. } DIUSAGEANDINST, *PDIUSAGEANDINST;
  130. #define MAX_BLOCKS 4 //we can send up to 4 blocks at a time -- 1 effect block, 2 param blocks & 1 effect operation block
  131. typedef struct CPidDrv
  132. {
  133. /* Supported interfaces */
  134. IDirectInputEffectDriver ed;
  135. ULONG cRef; /* Object reference count */
  136. /*
  137. * !!IHV!! Add additional instance data here.
  138. * (e.g., handle to driver you want to IOCTL to)
  139. */
  140. DWORD dwDirectInputVersion;
  141. DWORD dwID;
  142. TCHAR tszDeviceInterface[MAX_DEVICEINTERFACE];
  143. GUID GuidInstance;
  144. HANDLE hdev;
  145. PHIDP_PREPARSED_DATA \
  146. ppd;
  147. HIDD_ATTRIBUTES attr;
  148. HIDP_CAPS caps;
  149. PUCHAR pReport[HidP_Max];
  150. USHORT cbReport[HidP_Max];
  151. //here we store reports that need to be written in a non-blocking way
  152. PUCHAR pWriteReport[MAX_BLOCKS];
  153. USHORT cbWriteReport[MAX_BLOCKS];
  154. PHIDP_LINK_COLLECTION_NODE pLinkCollection;
  155. USHORT cMaxEffects;
  156. USHORT cMaxParameters;
  157. /*
  158. * We remember the unit number because that tells us
  159. * which I/O port we need to send the commands to.
  160. */
  161. DWORD dwUnit; /* Device unit number */
  162. UINT uDeviceManaged;
  163. UINT cFFObjMax;
  164. UINT cFFObj;
  165. PDIUSAGEANDINST rgFFUsageInst;
  166. REPORTPOOL ReportPool;
  167. SZPOOL SzPool;
  168. INT_PTR iUnitStateOffset;
  169. DIEFFECT DiSEffectScale;
  170. DIEFFECT DiSEffectOffset;
  171. DIENVELOPE DiSEnvScale;
  172. DIENVELOPE DiSEnvOffset;
  173. DICONDITION DiSCondScale;
  174. DICONDITION DiSCondOffset;
  175. DIRAMPFORCE DiSRampScale;
  176. DIRAMPFORCE DiSRampOffset;
  177. DIPERIODIC DiSPeriodicScale;
  178. DIPERIODIC DiSPeriodicOffset;
  179. DICONSTANTFORCE DiSConstScale;
  180. DICONSTANTFORCE DiSConstOffset;
  181. DICUSTOMFORCE DiSCustomScale;
  182. DICUSTOMFORCE DiSCustomOffset;
  183. DWORD DiSEffectAngleScale[MAX_ORDINALS];
  184. DWORD DiSEffectAngleOffset[MAX_ORDINALS];
  185. DWORD DiSCustomSample[MAX_ORDINALS];
  186. HIDP_VALUE_CAPS customCaps[3];
  187. HIDP_VALUE_CAPS customDataCaps;
  188. HANDLE hThread;
  189. DWORD idThread;
  190. ULONG cThreadRef;
  191. HANDLE hdevOvrlp;
  192. OVERLAPPED o;
  193. HANDLE hWrite;
  194. HANDLE hWriteComplete;
  195. DWORD dwWriteAttempt;
  196. UINT totalBlocks; //how many total blocks we need to write
  197. UINT blockNr; //the block we're currently writing
  198. DWORD dwState;
  199. DWORD dwUsedMem;
  200. } CPidDrv, *PCPidDrv;
  201. /*****************************************************************************
  202. *
  203. * @doc INTERNAL
  204. *
  205. * @struct EFFECTMAPINFO |
  206. *
  207. * Information about an effect, much like a
  208. * <t DIEFFECTINFO>, but containing the
  209. * effect ID, too.
  210. *
  211. * @field DWORD | dwId |
  212. *
  213. * The effect ID. This comes first so we can copy
  214. * an <t EFFECTMAPINFO> into a <t DIEFFECTINFO>
  215. * all at one go.
  216. *
  217. * @field GUID | guid |
  218. *
  219. * The effect GUID.
  220. *
  221. * @field DWORD | dwEffType |
  222. *
  223. * The effect type and flags.
  224. *
  225. * @field WCHAR | wszName[MAX_PATH] |
  226. *
  227. * The name for the effect.
  228. *
  229. *****************************************************************************/
  230. typedef struct _EFFECTMAPINFO
  231. {
  232. DIEFFECTATTRIBUTES attr;
  233. PCGUID pcguid;
  234. TCHAR tszName[MAX_PATH];
  235. } EFFECTMAPINFO, *PEFFECTMAPINFO;
  236. typedef const EFFECTMAPINFO *PCEFFECTMAPINFO;
  237. typedef struct _PIDSUPPORT
  238. {
  239. DWORD dwDIFlags;
  240. DWORD dwPidUsage;
  241. USAGE Type;
  242. HIDP_REPORT_TYPE HidP_Type;
  243. } PIDSUPPORT, *PPIDSUPPORT;
  244. typedef struct _PIDUSAGE
  245. {
  246. DWORD dwUsage;
  247. UINT DataOffset;
  248. } PIDUSAGE, *PPIDUSAGE;
  249. typedef struct _PIDREPORT
  250. {
  251. HIDP_REPORT_TYPE HidP_Type;
  252. USAGE UsagePage;
  253. USAGE Collection;
  254. UINT cbXData;
  255. UINT cAPidUsage;
  256. PPIDUSAGE rgPidUsage;
  257. } PIDREPORT, *PPIDREPORT;
  258. extern PIDREPORT g_BlockIndex;
  259. extern PIDREPORT g_Effect;
  260. extern PIDREPORT g_Condition;
  261. extern PIDREPORT g_Periodic;
  262. extern PIDREPORT g_Ramp;
  263. extern PIDREPORT g_Envelope;
  264. extern PIDREPORT g_Constant;
  265. extern PIDREPORT g_Direction;
  266. extern PIDREPORT g_TypeSpBlockOffset;
  267. extern PIDREPORT g_PoolReport;
  268. extern PIDREPORT g_BlockIndexIN;
  269. extern PIDREPORT g_Custom;
  270. extern PIDREPORT g_CustomSample;
  271. extern PIDREPORT g_CustomData;
  272. #pragma BEGIN_CONST_DATA
  273. static PIDUSAGE c_rgUsgDirection[]=
  274. {
  275. MAKE_HIDUSAGE(GENERIC, HID_USAGE_GENERIC_RX, 0*cbX(ULONG)),
  276. MAKE_HIDUSAGE(GENERIC, HID_USAGE_GENERIC_RY, 1*cbX(ULONG)),
  277. MAKE_HIDUSAGE(GENERIC, HID_USAGE_GENERIC_RZ, 2*cbX(ULONG)),
  278. };
  279. /*
  280. * Define translation table for ordinals to HID usages
  281. */
  282. static PIDUSAGE c_rgUsgOrdinals[] =
  283. {
  284. MAKE_HIDUSAGE(ORDINAL, 0x1, 0*cbX(ULONG)),
  285. MAKE_HIDUSAGE(ORDINAL, 0x2, 1*cbX(ULONG)),
  286. MAKE_HIDUSAGE(ORDINAL, 0x3, 2*cbX(ULONG)),
  287. MAKE_HIDUSAGE(ORDINAL, 0x4, 3*cbX(ULONG)),
  288. MAKE_HIDUSAGE(ORDINAL, 0x5, 4*cbX(ULONG)),
  289. MAKE_HIDUSAGE(ORDINAL, 0x6, 5*cbX(ULONG)),
  290. MAKE_HIDUSAGE(ORDINAL, 0x7, 6*cbX(ULONG)),
  291. MAKE_HIDUSAGE(ORDINAL, 0x8, 7*cbX(ULONG)),
  292. };
  293. #pragma END_CONST_DATA
  294. typedef BOOL (WINAPI *CANCELIO)(HANDLE);
  295. typedef BOOL (WINAPI *TRYENTERCRITICALSECTION)(LPCRITICAL_SECTION);
  296. BOOL WINAPI FakeCancelIO(HANDLE h);
  297. BOOL WINAPI FakeTryEnterCriticalSection(LPCRITICAL_SECTION lpCrit_sec);
  298. extern CANCELIO CancelIo_;
  299. extern TRYENTERCRITICALSECTION TryEnterCriticalSection_;
  300. /*****************************************************************************
  301. *
  302. * Constant globals: Never change. Ever.
  303. *
  304. *****************************************************************************/
  305. DEFINE_GUID(GUID_MySharedMemory, 0x1dc900bf,0xbcac,0x11d2,0xa9,0x19,0x00,0xc0,0x4f,0xb9,0x86,0x38);
  306. DEFINE_GUID(GUID_MyMutex, 0x4368208f,0xbcac,0x11d2,0xa9,0x19,0x00,0xc0,0x4f,0xb9,0x86,0x38);
  307. /*****************************************************************************
  308. *
  309. * Static globals: Initialized at PROCESS_ATTACH and never modified.
  310. *
  311. *****************************************************************************/
  312. extern HINSTANCE g_hinst; /* This DLL's instance handle */
  313. extern PSHAREDMEMORY g_pshmem; /* Our shared memory block */
  314. extern HANDLE g_hfm; /* Handle to file mapping object */
  315. extern HANDLE g_hmtxShared; /* Handle to mutex that protects g_pshmem */
  316. /*****************************************************************************
  317. *
  318. * Prototypes
  319. *
  320. *****************************************************************************/
  321. STDMETHODIMP
  322. PID_DownloadEffect
  323. (
  324. IDirectInputEffectDriver *ped,
  325. DWORD dwId,
  326. DWORD dwEffectId,
  327. LPDWORD pdwEffect,
  328. LPCDIEFFECT peff,
  329. DWORD dwFlags
  330. );
  331. STDMETHODIMP
  332. PID_DoParameterBlocks
  333. (
  334. IDirectInputEffectDriver *ped,
  335. DWORD dwId,
  336. DWORD dwEffectId,
  337. DWORD dwEffectIndex,
  338. LPCDIEFFECT peff,
  339. DWORD dwFlags,
  340. PUINT puParameter,
  341. BOOL bBlocking,
  342. UINT totalBlocks
  343. );
  344. STDMETHODIMP
  345. PID_EffectOperation
  346. (
  347. IDirectInputEffectDriver *ped,
  348. DWORD dwId,
  349. DWORD dwEffect,
  350. DWORD dwMode,
  351. DWORD dwCount,
  352. BOOL bBlocking,
  353. UINT blockNr,
  354. UINT totalBlocks
  355. );
  356. STDMETHODIMP
  357. PID_SetGain
  358. (
  359. IDirectInputEffectDriver *ped,
  360. DWORD dwId,
  361. DWORD dwGain
  362. );
  363. STDMETHODIMP
  364. PID_SendForceFeedbackCommand
  365. (
  366. IDirectInputEffectDriver *ped,
  367. DWORD dwId,
  368. DWORD dwCommand
  369. );
  370. STDMETHODIMP
  371. PID_GetLinkCollectionIndex
  372. (
  373. IDirectInputEffectDriver *ped,
  374. USAGE UsagePage,
  375. USAGE Collection,
  376. USHORT Parent,
  377. PUSHORT puLinkCollection
  378. );
  379. STDMETHODIMP
  380. PID_Init
  381. (
  382. IDirectInputEffectDriver *ped
  383. );
  384. STDMETHODIMP
  385. PID_InitFFAttributes
  386. (
  387. IDirectInputEffectDriver *ped
  388. );
  389. STDMETHODIMP
  390. PID_Finalize
  391. (
  392. IDirectInputEffectDriver *ped
  393. );
  394. STDMETHODIMP
  395. PID_InitRegistry
  396. (
  397. IDirectInputEffectDriver *ped
  398. );
  399. STDMETHODIMP
  400. PID_Support
  401. (
  402. IDirectInputEffectDriver *ped,
  403. UINT cAPidSupport,
  404. PPIDSUPPORT rgPidSupport,
  405. PDWORD pdwFlags
  406. );
  407. STDMETHODIMP
  408. PID_PackValue
  409. (
  410. IDirectInputEffectDriver *ped,
  411. PPIDREPORT pPidReport,
  412. USHORT LinkCollection,
  413. PVOID pvData,
  414. UINT cbData,
  415. PCHAR pReport,
  416. ULONG cbReport
  417. );
  418. STDMETHODIMP
  419. PID_ParseReport
  420. (
  421. IDirectInputEffectDriver *ped,
  422. PPIDREPORT pPidReport,
  423. USHORT LinkCollection,
  424. PVOID pvData,
  425. UINT cbData,
  426. PCHAR pReport,
  427. ULONG cbReport
  428. );
  429. STDMETHODIMP
  430. PID_SendReport
  431. (
  432. IDirectInputEffectDriver *ped,
  433. PUCHAR pReport,
  434. UINT cbReport,
  435. HIDP_REPORT_TYPE HidP_Type,
  436. BOOL bBlocking,
  437. UINT blockNr,
  438. UINT totalBlocks
  439. );
  440. STDMETHODIMP
  441. PID_GetReport
  442. (
  443. IDirectInputEffectDriver *ped,
  444. PPIDREPORT pPidReport,
  445. USHORT LinkCollection,
  446. PVOID pReport,
  447. UINT cbReport
  448. );
  449. STDMETHODIMP
  450. PID_NewEffectIndex
  451. (
  452. IDirectInputEffectDriver *ped,
  453. LPDIEFFECT lpdieff,
  454. DWORD dwEffectId,
  455. PDWORD pdwEffect
  456. );
  457. STDMETHODIMP
  458. PID_ValidateEffectIndex
  459. (
  460. IDirectInputEffectDriver *ped,
  461. DWORD pdwEffect
  462. );
  463. STDMETHODIMP
  464. PID_DestroyEffect
  465. (
  466. IDirectInputEffectDriver *ped,
  467. DWORD dwId,
  468. DWORD dwEffect
  469. );
  470. STDMETHODIMP
  471. PID_GetParameterOffset
  472. (
  473. IDirectInputEffectDriver *ped,
  474. DWORD dwEffectIndex,
  475. UINT uParameterBlock,
  476. DWORD dwSz,
  477. PLONG plValue
  478. );
  479. STDMETHODIMP
  480. PID_ComputeScalingFactors
  481. (
  482. IDirectInputEffectDriver *ped,
  483. PPIDREPORT pPidReport,
  484. USHORT LinkCollection,
  485. PVOID pvData,
  486. UINT cbData,
  487. PVOID pvOffset,
  488. UINT cbOffset
  489. );
  490. STDMETHODIMP
  491. PID_ApplyScalingFactors
  492. (
  493. IDirectInputEffectDriver *ped,
  494. PPIDREPORT pPidReport,
  495. PVOID pvScale,
  496. UINT cbScale,
  497. PVOID pvOffset,
  498. UINT cbOffset,
  499. PVOID pvData,
  500. UINT cbData
  501. );
  502. STDMETHODIMP
  503. PID_GetReportId
  504. (
  505. IDirectInputEffectDriver *ped,
  506. PPIDREPORT pPidReport,
  507. USHORT uLinkCollection,
  508. UCHAR* pReportId
  509. );
  510. VOID INTERNAL
  511. PID_ThreadProc(CPidDrv* this);
  512. STDMETHODIMP_(ULONG)
  513. PID_AddRef(IDirectInputEffectDriver *ped);
  514. STDMETHODIMP_(ULONG)
  515. PID_Release(IDirectInputEffectDriver *ped);
  516. void EXTERNAL
  517. NameFromGUID(LPTSTR ptszBuf, PCGUID pguid);
  518. #ifdef DEBUG
  519. #define PIDUSAGETXT_MAX ( 0xAC )
  520. extern PTCHAR g_rgUsageTxt[PIDUSAGETXT_MAX]; // Cheat sheet for EffectNames
  521. #define PIDUSAGETXT(UsagePage, Usage ) \
  522. ( ( UsagePage == HID_USAGE_PAGE_PID && Usage < PIDUSAGETXT_MAX) ? g_rgUsageTxt[Usage] : NULL )
  523. void PID_CreateUsgTxt();
  524. #else
  525. #define PID_CreateUsgTxt()
  526. #define PIDUSAGETXT(UsagePage, Usage) ( NULL )
  527. #endif
  528. PEFFECTSTATE INLINE PeffectStateFromBlockIndex(PCPidDrv this, UINT Index )
  529. {
  530. return (PEFFECTSTATE)(&((PUNITSTATE)(g_pshmem + this->iUnitStateOffset))->State[0] + (Index-1) * ((FIELD_OFFSET(EFFECTSTATE,PidMem)) + this->cMaxParameters*cbX(PIDMEM)));
  531. }
  532. #define PID_EFFECT_RESET (0x0000000)
  533. #define PID_EFFECT_BUSY (0x8000000)
  534. #define PID_EFFECT_STARTED (0x4000000)
  535. #define PID_EFFECT_STARTED_SOLO (0x2000000)
  536. #define PID_DRIVER_VERSION (0x0000001)
  537. #define PID_DEVICEMANAGED (0x1)
  538. #define PID_SHAREDPARAM (0x2)
  539. /*****************************************************************************
  540. *
  541. * Dll global functions
  542. *
  543. *****************************************************************************/
  544. void EXTERNAL DllEnterCrit_(LPCTSTR lptszFile, UINT line);
  545. void EXTERNAL DllLeaveCrit_(LPCTSTR lptszFile, UINT line);
  546. #ifdef DEBUG
  547. BOOL EXTERNAL DllInCrit(void);
  548. #define DllEnterCrit() DllEnterCrit_(TEXT(__FILE__), __LINE__)
  549. #define DllLeaveCrit() DllLeaveCrit_(TEXT(__FILE__), __LINE__)
  550. #else
  551. #define DllEnterCrit() DllEnterCrit_(NULL, 0x0)
  552. #define DllLeaveCrit() DllLeaveCrit_(NULL, 0x0)
  553. #endif
  554. STDAPI_(ULONG) DllAddRef(void);
  555. STDAPI_(ULONG) DllRelease(void);
  556. /*****************************************************************************
  557. *
  558. * Class factory
  559. *
  560. *****************************************************************************/
  561. STDAPI CClassFactory_New(REFIID riid, LPVOID *ppvObj);
  562. /*****************************************************************************
  563. *
  564. * Effect driver
  565. *
  566. *****************************************************************************/
  567. STDAPI PID_New(REFIID riid, LPVOID *ppvObj);
  568. #ifndef WINNT
  569. /***************************************************************************
  570. *
  571. * KERNEL32 prototypes missing from Win98 headers.
  572. *
  573. ***************************************************************************/
  574. WINBASEAPI BOOL WINAPI CancelIo( HANDLE hFile );
  575. #endif