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.

444 lines
12 KiB

  1. //***************************************************************************
  2. //
  3. //
  4. //
  5. //***************************************************************************
  6. // Macros:
  7. #define CreateSemaphore() (VMM_Create_Semaphore(0))
  8. #define DestroySemaphore(_s) (VMM_Destroy_Semaphore(_s))
  9. #define signal(_s) (VMM_Signal_Semaphore(_s))
  10. #define wait(_s) (VMM_Wait_Semaphore_Ints(_s))
  11. #define wait_idle(_s) (VMM_Wait_Semaphore_Idle(_s))
  12. #define CreateResourceLock() (VMM_Create_Semaphore(1))
  13. #define DestroyResourceLock(_s) (VMM_Destroy_Semaphore(_s))
  14. #define lock(_s) (VMM_Wait_Semaphore_Ints(_s))
  15. #define unlock(_s) (VMM_Signal_Semaphore(_s))
  16. #define WANTVXDWRAPS
  17. #include <basedef.h>
  18. #include <vmm.h>
  19. #include <vcomm.h>
  20. #include <debug.h>
  21. #include <vxdwraps.h>
  22. #include <configmg.h>
  23. #include <vwin32.h>
  24. #include <winerror.h>
  25. typedef DIOCPARAMETERS *LPDIOC;
  26. #pragma VxD_LOCKED_CODE_SEG
  27. #pragma VxD_LOCKED_DATA_SEG
  28. #define ASSERT(_A) if(!(_A)){_asm int 3}
  29. DWORD _stdcall LogInit(DWORD dwDDB, DWORD hDevice, LPDIOC lpDIOCParams);
  30. DWORD _stdcall LogWrite(DWORD dwDDB, DWORD hDevice, LPDIOC lpDIOCParams);
  31. DWORD _stdcall StatsWrite(DWORD dwDDB, DWORD hDevice, LPDIOC lpDIOCParams);
  32. #define FIRST_DEBUG_PROC 100
  33. DWORD ( _stdcall *DebugProcs[] )(DWORD, DWORD, LPDIOC) = {
  34. LogInit,
  35. LogWrite,
  36. StatsWrite
  37. };
  38. #define MAX_DEBUG_PROC (sizeof(DebugProcs)/sizeof(DWORD)+FIRST_DEBUG_PROC-1)
  39. typedef struct _LOGENTRY {
  40. DWORD ThreadHandle;
  41. DWORD tLogged;
  42. CHAR debuglevel;
  43. CHAR str[1];
  44. } LOGENTRY, *PLOGENTRY;
  45. PUCHAR pLog=NULL;
  46. UINT nCharsPerLine;
  47. UINT nLogEntries;
  48. UINT iLogWritePos;
  49. UINT nLogEntriesInUse;
  50. UINT LogInitCount=0;
  51. UINT LogLevel=255;
  52. UINT LogExact=FALSE;
  53. UINT LogLock=0;
  54. #define Entry(_i) ((PLOGENTRY)(pLog+((sizeof(LOGENTRY)+nCharsPerLine)*_i)))
  55. typedef struct {
  56. UINT nLogEntries;
  57. UINT nCharsPerLine;
  58. } IN_LOGINIT, *PIN_LOGINIT;
  59. typedef struct {
  60. UINT hr;
  61. } OUT_LOGINIT, *POUT_LOGINIT;
  62. typedef struct {
  63. CHAR debuglevel;
  64. CHAR str[1];
  65. } IN_LOGWRITE, *PIN_LOGWRITE;
  66. typedef struct {
  67. UINT hr;
  68. } OUT_LOGWRITE, *POUT_LOGWRITE;
  69. extern UINT stat_ThrottleRate;
  70. extern UINT stat_BytesSent;
  71. extern UINT stat_BackLog;
  72. extern UINT stat_BytesLost;
  73. extern UINT stat_RemBytesReceived;
  74. extern UINT stat_Latency;
  75. extern UINT stat_MinLatency;
  76. extern UINT stat_AvgLatency;
  77. extern UINT stat_AvgDevLatency;
  78. extern UINT stat_USER1;
  79. extern UINT stat_USER2;
  80. extern UINT stat_USER3;
  81. extern UINT stat_USER4;
  82. extern UINT stat_USER5;
  83. extern UINT stat_USER6;
  84. typedef struct {
  85. UINT stat_ThrottleRate;
  86. UINT stat_BytesSent;
  87. UINT stat_BackLog;
  88. UINT stat_BytesLost;
  89. UINT stat_RemBytesReceived;
  90. UINT stat_Latency;
  91. UINT stat_MinLatency;
  92. UINT stat_AvgLatency;
  93. UINT stat_AvgDevLatency;
  94. UINT stat_USER1;
  95. UINT stat_USER2;
  96. UINT stat_USER3;
  97. UINT stat_USER4;
  98. UINT stat_USER5; // remote clock delta change from average
  99. UINT stat_USER6; // sign of change
  100. } IN_WRITESTATS, *PIN_WRITESTATS;
  101. typedef struct {
  102. UINT hr;
  103. } OUT_WRITESTATS, *POUT_WRITESTATS;
  104. VOID _stdcall ZeroStats();
  105. /****************************************************************************
  106. DPLAY_W32_DeviceIOControl
  107. ****************************************************************************/
  108. DWORD _stdcall DPLAY_W32_DeviceIOControl(DWORD dwService,
  109. DWORD dwDDB,
  110. DWORD hDevice,
  111. LPDIOC lpDIOCParms)
  112. {
  113. DWORD dwRetVal = 0;
  114. if ( dwService == DIOC_OPEN )
  115. {
  116. dwRetVal = 0; // I/F supported!
  117. }
  118. else if ( dwService == DIOC_CLOSEHANDLE )
  119. {
  120. if(LogInitCount)
  121. {
  122. if(!(--LogInitCount)){
  123. DestroyResourceLock(LogLock);
  124. LogLock=0;
  125. C_HeapFree(pLog);
  126. pLog=NULL;
  127. ZeroStats();
  128. }
  129. }
  130. dwRetVal = VXD_SUCCESS; // ok, we're closed.
  131. }
  132. else if ((dwService >= FIRST_DEBUG_PROC) && (dwService <= MAX_DEBUG_PROC))
  133. {
  134. dwRetVal = (DebugProcs[dwService-FIRST_DEBUG_PROC])
  135. (dwDDB, hDevice, lpDIOCParms);
  136. }
  137. else
  138. {
  139. dwRetVal = ERROR_NOT_SUPPORTED;
  140. }
  141. return(dwRetVal);
  142. }
  143. DWORD _stdcall LogInit(DWORD dwDDB, DWORD hDevice, LPDIOC lpDIOCParams)
  144. {
  145. PIN_LOGINIT pIn;
  146. POUT_LOGINIT pOut;
  147. UINT hr=0;
  148. pIn=(PIN_LOGINIT)lpDIOCParams->lpvInBuffer;
  149. pOut=(POUT_LOGINIT)lpDIOCParams->lpvOutBuffer;
  150. ASSERT(lpDIOCParams->cbInBuffer>=sizeof(IN_LOGINIT));
  151. ASSERT(lpDIOCParams->cbOutBuffer>=sizeof(OUT_LOGINIT));
  152. if(!LogInitCount){
  153. if(!pLog){
  154. LogLock=CreateResourceLock();
  155. nCharsPerLine = pIn->nCharsPerLine;
  156. nLogEntries = pIn->nLogEntries;
  157. iLogWritePos = 0;
  158. nLogEntriesInUse = 0;
  159. pLog=(CHAR *)C_HeapAllocate(pIn->nLogEntries*(sizeof(LOGENTRY)+pIn->nCharsPerLine),HEAPZEROINIT);
  160. }
  161. if(!pLog){
  162. pOut->hr=ERROR_NOT_ENOUGH_MEMORY;
  163. } else {
  164. DbgPrint("DPLAYVXD: Logging on, allocated %d entries of length %d each\n",pIn->nLogEntries,pIn->nCharsPerLine);
  165. pOut->hr=ERROR_SUCCESS;
  166. LogInitCount=1;
  167. }
  168. lpDIOCParams->lpcbBytesReturned=sizeof(OUT_LOGINIT);
  169. } else {
  170. pOut->hr=ERROR_SUCCESS;
  171. LogInitCount++;
  172. }
  173. return NO_ERROR;
  174. }
  175. DWORD _stdcall LogWrite(DWORD dwDDB, DWORD hDevice, LPDIOC lpDIOCParams)
  176. {
  177. PIN_LOGWRITE pIn;
  178. POUT_LOGWRITE pOut;
  179. pIn=(PIN_LOGWRITE)lpDIOCParams->lpvInBuffer;
  180. pOut=(POUT_LOGWRITE)lpDIOCParams->lpvOutBuffer;
  181. ASSERT(lpDIOCParams->cbInBuffer>=sizeof(IN_LOGWRITE));
  182. ASSERT(lpDIOCParams->cbOutBuffer>=sizeof(OUT_LOGWRITE));
  183. if(LogInitCount){
  184. UINT BytesToCopy;
  185. PLOGENTRY pLogEntry;
  186. // make sure NULL terminated string
  187. BytesToCopy=lpDIOCParams->cbInBuffer-sizeof(IN_LOGWRITE)+1;
  188. if(BytesToCopy > nCharsPerLine){
  189. BytesToCopy=nCharsPerLine;
  190. }
  191. pIn->str[BytesToCopy-1]=0;
  192. lock(LogLock);
  193. pLogEntry=Entry(iLogWritePos);
  194. if(iLogWritePos+1 > nLogEntriesInUse){
  195. nLogEntriesInUse+=1;
  196. }
  197. iLogWritePos=(iLogWritePos+1)%nLogEntries;
  198. pLogEntry->ThreadHandle=GetThreadHandle();
  199. pLogEntry->tLogged=VMM_Get_System_Time();
  200. memcpy(&pLogEntry->debuglevel,pIn,BytesToCopy+sizeof(IN_LOGWRITE)-1);
  201. unlock(LogLock);
  202. pOut->hr=ERROR_SUCCESS;
  203. } else {
  204. pOut->hr=0x80000008;//E_FAIL
  205. }
  206. return NO_ERROR;
  207. }
  208. VOID SetLogLevel(UINT level, UINT fExact)
  209. {
  210. LogExact=fExact;
  211. LogLevel=level;
  212. if(LogExact)
  213. {
  214. DbgPrint("DPLAY VXD: Log printing is Exact at level %d\n",LogLevel);
  215. } else {
  216. DbgPrint("DPLAY VXD: Log printing is level %d and below\n",LogLevel);
  217. }
  218. }
  219. DumpLogEntry(PLOGENTRY pLogEntry, UINT i, BOOL fResetTimeBase)
  220. {
  221. static UINT timebase=0;
  222. if(pLogEntry){
  223. DbgPrint("%4d: %8x %6d %2x %s\n",i,pLogEntry->ThreadHandle, pLogEntry->tLogged-timebase,pLogEntry->debuglevel, pLogEntry->str);
  224. timebase=pLogEntry->tLogged;
  225. }
  226. if(fResetTimeBase){
  227. timebase=0;
  228. }
  229. }
  230. VOID DumpLog(UINT relstart)
  231. {
  232. UINT nToDump=50;
  233. UINT c=0,i;
  234. PLOGENTRY pLogEntry;
  235. UINT start;
  236. start=relstart;
  237. if(nLogEntriesInUse==nLogEntries){
  238. start=(iLogWritePos+start)%nLogEntries;
  239. }
  240. DumpLogEntry(NULL, 0, TRUE);
  241. DbgPrint("Total Entries: %d, Current Position %d, dumping from record %d, %d ahead of start\n",nLogEntriesInUse,iLogWritePos,start,relstart);
  242. for(i=start;i<nLogEntries && c<nToDump;i++){
  243. pLogEntry=Entry(i);
  244. if((LogExact)?(pLogEntry->debuglevel==LogLevel):(pLogEntry->debuglevel<=LogLevel)){
  245. c++;
  246. DumpLogEntry(pLogEntry,i,FALSE);
  247. }
  248. }
  249. // Dump from beginning to current pos.
  250. for(i=0;i<iLogWritePos && c<nToDump;i++,c++){
  251. if((LogExact)?(pLogEntry->debuglevel==LogLevel):(pLogEntry->debuglevel<=LogLevel)){
  252. c++;
  253. DumpLogEntry(pLogEntry,i,FALSE);
  254. }
  255. }
  256. }
  257. VOID DumpLogLast(UINT nToDump)
  258. {
  259. UINT c=0,i;
  260. PLOGENTRY pLogEntry;
  261. UINT start;
  262. //BUGBUG: only works when all debug levels being dumped.
  263. if(iLogWritePos > nToDump){
  264. start=(iLogWritePos-nToDump);
  265. }else{
  266. start=(nLogEntries-(nToDump-iLogWritePos));
  267. }
  268. DumpLogEntry(NULL,0,TRUE);
  269. DbgPrint("Total Entries: %d, Current Position %d, dumping from record %d\n",nLogEntriesInUse,iLogWritePos,start);
  270. for(i=start;i<nLogEntries && c<nToDump;i++){
  271. pLogEntry=Entry(i);
  272. if((LogExact)?(pLogEntry->debuglevel==LogLevel):(pLogEntry->debuglevel<=LogLevel)){
  273. c++;
  274. DumpLogEntry(pLogEntry,i,FALSE);
  275. }
  276. }
  277. // Dump from beginning to current pos.
  278. for(i=0;i<iLogWritePos && c<nToDump;i++,c++){
  279. pLogEntry=Entry(i);
  280. if((LogExact)?(pLogEntry->debuglevel==LogLevel):(pLogEntry->debuglevel<=LogLevel)){
  281. c++;
  282. DumpLogEntry(pLogEntry,i,FALSE);
  283. }
  284. }
  285. }
  286. VOID DumpWholeLog(VOID)
  287. {
  288. UINT i;
  289. PLOGENTRY pLogEntry;
  290. DumpLogEntry(NULL,0,TRUE);
  291. // Dump from 1 after current pos to end.
  292. if(nLogEntriesInUse==nLogEntries){
  293. for(i=iLogWritePos;i<nLogEntries;i++){
  294. pLogEntry=Entry(i);
  295. if((LogExact)?(pLogEntry->debuglevel==LogLevel):(pLogEntry->debuglevel<=LogLevel)){
  296. DumpLogEntry(pLogEntry,i,FALSE);
  297. }
  298. }
  299. }
  300. // Dump from beginning to current pos.
  301. for(i=0;i<iLogWritePos;i++){
  302. pLogEntry=Entry(i);
  303. if((LogExact)?(pLogEntry->debuglevel==LogLevel):(pLogEntry->debuglevel<=LogLevel)){
  304. DumpLogEntry(pLogEntry,i,FALSE);
  305. }
  306. }
  307. }
  308. DWORD _stdcall StatsWrite(DWORD dwDDB, DWORD hDevice, LPDIOC lpDIOCParams)
  309. {
  310. PIN_WRITESTATS pIn;
  311. POUT_WRITESTATS pOut;
  312. UINT hr=0;
  313. DWORD cbInBuffer;
  314. pIn=(PIN_WRITESTATS)lpDIOCParams->lpvInBuffer;
  315. pOut=(POUT_WRITESTATS)lpDIOCParams->lpvOutBuffer;
  316. ASSERT(lpDIOCParams->cbInBuffer>=sizeof(DWORD));
  317. ASSERT(lpDIOCParams->cbOutBuffer>=sizeof(OUT_WRITESTATS));
  318. cbInBuffer=lpDIOCParams->cbInBuffer;
  319. if(pIn->stat_ThrottleRate!=0xFFFFFFFF)stat_ThrottleRate=pIn->stat_ThrottleRate;
  320. cbInBuffer-=sizeof(DWORD);if(!cbInBuffer)goto end;
  321. if(pIn->stat_BytesSent!=0xFFFFFFFF)stat_BytesSent=pIn->stat_BytesSent;
  322. cbInBuffer-=sizeof(DWORD);if(!cbInBuffer)goto end;
  323. if(pIn->stat_BackLog!=0xFFFFFFFF)stat_BackLog=pIn->stat_BackLog;
  324. cbInBuffer-=sizeof(DWORD);if(!cbInBuffer)goto end;
  325. if(pIn->stat_BytesLost!=0xFFFFFFFF)stat_BytesLost=pIn->stat_BytesLost;
  326. cbInBuffer-=sizeof(DWORD);if(!cbInBuffer)goto end;
  327. if(pIn->stat_RemBytesReceived!=0xFFFFFFFF)stat_RemBytesReceived=pIn->stat_RemBytesReceived;
  328. cbInBuffer-=sizeof(DWORD);if(!cbInBuffer)goto end;
  329. if(pIn->stat_Latency!=0xFFFFFFFF)stat_Latency=pIn->stat_Latency;
  330. cbInBuffer-=sizeof(DWORD);if(!cbInBuffer)goto end;
  331. if(pIn->stat_MinLatency!=0xFFFFFFFF)stat_MinLatency=pIn->stat_MinLatency;
  332. cbInBuffer-=sizeof(DWORD);if(!cbInBuffer)goto end;
  333. if(pIn->stat_AvgLatency!=0xFFFFFFFF)stat_AvgLatency=pIn->stat_AvgLatency;
  334. cbInBuffer-=sizeof(DWORD);if(!cbInBuffer)goto end;
  335. if(pIn->stat_AvgDevLatency!=0xFFFFFFFF)stat_AvgDevLatency=pIn->stat_AvgDevLatency;
  336. cbInBuffer-=sizeof(DWORD);if(!cbInBuffer)goto end;
  337. if(pIn->stat_USER1!=0xFFFFFFFF)stat_USER1=pIn->stat_USER1;
  338. cbInBuffer-=sizeof(DWORD);if(!cbInBuffer)goto end;
  339. if(pIn->stat_USER2!=0xFFFFFFFF)stat_USER2=pIn->stat_USER2;
  340. cbInBuffer-=sizeof(DWORD);if(!cbInBuffer)goto end;
  341. if(pIn->stat_USER3!=0xFFFFFFFF)stat_USER3=pIn->stat_USER3;
  342. cbInBuffer-=sizeof(DWORD);if(!cbInBuffer)goto end;
  343. if(pIn->stat_USER4!=0xFFFFFFFF)stat_USER4=pIn->stat_USER4;
  344. cbInBuffer-=sizeof(DWORD);if(!cbInBuffer)goto end;
  345. if(pIn->stat_USER5!=0xFFFFFFFF)stat_USER5=pIn->stat_USER5;
  346. cbInBuffer-=sizeof(DWORD);if(!cbInBuffer)goto end;
  347. if(pIn->stat_USER6!=0xFFFFFFFF)stat_USER6=pIn->stat_USER6;
  348. end:
  349. pOut->hr=ERROR_SUCCESS;
  350. return NO_ERROR;
  351. }
  352. VOID _stdcall ZeroStats()
  353. {
  354. stat_ThrottleRate=0;
  355. stat_BytesSent=0;
  356. stat_BackLog=0;
  357. stat_BytesLost=0;
  358. stat_RemBytesReceived=0;
  359. stat_Latency=0;
  360. stat_MinLatency=0;
  361. stat_AvgLatency=0;
  362. stat_AvgDevLatency=0;
  363. stat_USER1=0;
  364. stat_USER2=0;
  365. stat_USER3=0;
  366. stat_USER4=0;
  367. stat_USER5=0;
  368. stat_USER6=0;
  369. }