cryptlib  3.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros
os2.c
Go to the documentation of this file.
1 /****************************************************************************
2 * *
3 * OS/2 Randomness-Gathering Code *
4 * Copyright Peter Gutmann and Stuart Woolford 1996-2001 *
5 * Updated by Mario Korva 1998 *
6 * *
7 ****************************************************************************/
8 
9 /* This module is part of the cryptlib continuously seeded pseudorandom
10  number generator. For usage conditions, see random.c */
11 
12 /* General includes */
13 
14 #include "crypt.h"
15 
16 #define INCL_DOSMISC
17 #define INCL_DOSDATETIME
18 #define INCL_DOSPROCESS
19 #define INCL_WINWINDOWMGR
20 #define INCL_WINSYS
21 #include <os2.h>
22 
23 /* The size of the intermediate buffer used to accumulate polled data */
24 
25 #define RANDOM_BUFSIZE 4096
26 
27 /* DosQProcStatus() = DOSCALLS.154 */
28 
29 #if defined(__32BIT__)
30  #define PTR(ptr, ofs) ((void *) ((char *) (ptr) + (ofs)))
31 #else
32  #define DosQueryModuleName DosGetModName
33  #define APIENTRY16 APIENTRY
34  #if defined(M_I86SM) || defined(M_I86MM)
35  #define PTR(ptr, ofs) ((void *) ((char *) (ptr) + (ofs)))
36  #else
37  #define PTR(ptr, ofs) ((void *) ((char *) (((ULONG) procstat & 0xFFFF0000) | (USHORT) (ptr)) + (ofs)))
38  /* kludge to transform 0:32 into 16:16 pointer in this special case */
39  #endif
40 #endif
41 
42 #ifdef __EMX__
43 
44 USHORT _THUNK_FUNCTION(DosQProcStatus) (PVOID pBuf, USHORT cbBuf);
45 USHORT _THUNK_FUNCTION(DosGetPrty) (USHORT usScope, PUSHORT pusPriority, USHORT pid);
46 
47 USHORT _DosQProcStatus(PVOID pBuf, USHORT cbBuf)
48 {
49  _THUNK_PROLOG(4+2);
50  _THUNK_FAR16(_emx_32to16(pBuf)); /* PVOID pBuf = 4 bytes */
51  _THUNK_SHORT(cbBuf); /* USHORT cbBuf = 2 bytes */
52  return (USHORT) _THUNK_CALL(DosQProcStatus);
53 }
54 
55 #define DosQProcStatus _DosQProcStatus
56 
57 #else
58 
59 USHORT APIENTRY16 DosQProcStatus(PVOID pBuf, USHORT cbBuf);
60 
61 #endif
62 
63 /* DosQProcStatus()
64  Query Process Status Info API used by PSTAT system utility.
65  To use this undocumented function add following to DEF file:
66 IMPORTS
67  DOSQPROCSTATUS = DOSCALLS.154
68 
69 
70  The DosQProcStatus API is a 16 bit API that returns information that
71  summarizes the system resources that are in use of an OS/2 2.0 system.
72  DosQProcStatus reports on the following classes of OS/2 2.0 system resources:
73 
74  Processes and Threads
75  Dynamic Link Library Modules
76  16 bit System Semaphores
77  Named Shared Memory Segments
78 
79  DosQProcStatus returns a buffer that is filled with a series of sections
80  of resource information:
81 
82  1. Pointer section
83  2. Global data section
84  3. Section with Process and Thread records - one Process record for each process
85  immediately followed by a set of Thread records - one Thread record for each
86  thread within the process
87  4. Section consisting of 16 Bit System Semaphore records
88  5. Section consisting of Executable Module records
89  6. Section consisting of Shared Memory Segment records
90 
91  Definition of system records returned by DosQProcStatus()
92  from IBM document entitled:
93 
94  DosQProcStatus API for IBM OS/2 Version 2.0
95  May 11, 1992 */
96 
97 typedef struct qsGrec_s { /* Global record */
98  ULONG cThrds; /* number of threads in use */
99  ULONG Reserved1;
100  ULONG Reserved2;
101 }qsGrec_t;
102 
103 typedef struct qsTrec_s { /* Thread record */
104  ULONG RecType; /* Record Type */
105  /* Thread rectype = 100 */
106  USHORT tid; /* thread ID */
107  USHORT slot; /* "unique" thread slot number */
108  ULONG sleepid; /* sleep id thread is sleeping on */
109  ULONG priority; /* thread priority */
110  ULONG systime; /* thread system time */
111  ULONG usertime; /* thread user time */
112  UCHAR state; /* thread state */
113  UCHAR padchar; /* ? */
114  USHORT padshort; /* ? */
115 } qsTrec_t;
116 
117 typedef struct qsPrec_s { /* Process record */
118  ULONG RecType; /* type of record being processed */
119  /* process rectype = 1 */
120  qsTrec_t FAR *pThrdRec; /* ptr to 1st thread rec for this prc*/
121  USHORT pid; /* process ID */
122  USHORT ppid; /* parent process ID */
123  ULONG type; /* process type */
124  ULONG stat; /* process status */
125  ULONG sgid; /* process screen group */
126  USHORT hMte; /* program module handle for process */
127  USHORT cTCB; /* # of TCBs in use in process */
128  ULONG Reserved1;
129  void FAR *Reserved2;
130  USHORT c16Sem; /*# of 16 bit system sems in use by proc*/
131  USHORT cLib; /* number of runtime linked libraries */
132  USHORT cShrMem; /* number of shared memory handles */
133  USHORT Reserved3;
134  USHORT FAR *p16SemRec; /*ptr to head of 16 bit sem inf for proc*/
135  USHORT FAR *pLibRec; /*ptr to list of runtime lib in use by */
136  /*process*/
137  USHORT FAR *pShrMemRec; /*ptr to list of shared mem handles in */
138  /*use by process*/
139  USHORT FAR *Reserved4;
140 } qsPrec_t;
141 
142 typedef struct qsS16Headrec_s { /* 16 Bit System Semaphore record */
143  ULONG SRecType; /* semaphore rectype = 3 */
144  ULONG Reserved1; /* overlays NextRec of 1st qsS16rec_t*/
145  ULONG Reserved2;
146  ULONG S16TblOff; /* index of first semaphore,SEE PSTAT OUTPUT*/
147  /* System Semaphore Information Section */
149 
150 typedef struct qsMrec_s { /* Shared Memory Segment record */
151  ULONG MemNextRec; /* offset to next record in buffer */
152  USHORT hmem; /* handle for shared memory */
153  USHORT sel; /* shared memory selector */
154  USHORT refcnt; /* reference count */
155  CHAR Memname; /* start of shared memory name string */
156 } qsMrec_t;
157 
158 typedef struct qsLrec_s { /* Executable Module record */
159  void FAR *pNextRec; /* pointer to next record in buffer */
160  USHORT hmte; /* handle for this mte */
161  USHORT Reserved1; /* Reserved */
162  ULONG ctImpMod; /* # of imported modules in table */
163  ULONG Reserved2; /* Reserved */
164  ULONG Reserved3; /* Reserved */
165  UCHAR FAR *pName; /* ptr to name string following stru */
166 } qsLrec_t;
167 
168 typedef struct qsPtrRec_s { /* Pointer record */
169  qsGrec_t *pGlobalRec; /* ptr to the global data section */
170  qsPrec_t *pProcRec; /* ptr to process record section */
171  qsS16Headrec_t *p16SemRec; /* ptr to 16 bit sem section */
172  qsMrec_t *pShrMemRec; /* ptr to shared mem section */
173  qsLrec_t *pLibRec; /* ptr to exe module record section */
174 } qsPtrRec_t;
175 
176 void fastPoll( void )
177  {
178  static BOOLEAN addedFixedItems = FALSE;
179  RANDOM_STATE randomState;
180  BYTE buffer[ RANDOM_BUFSIZE + 8 ];
181  DATETIME dt;
182  ULONG querybuffer[ 26 + 8 ];
183  PTIB ptib = NULL;
184  PPIB ppib = NULL;
185 
186  initRandomData( randomState, buffer, RANDOM_BUFSIZE );
187 
188  /* Get various (fairly constant) pieces of machine information and
189  timestamps, date and time, the thread information block and process
190  information block. The DosQuerySysInfo() call returns more or less
191  static information with a single 32-bit counter which is incremented
192  roughly every 31ms */
193  DosQuerySysInfo( 1, 26, ( PVOID ) querybuffer, sizeof( querybuffer ) );
194  addRandomData( randomState, querybuffer, sizeof( querybuffer ) );
195  DosGetDateTime( &dt );
196  addRandomData( randomState, &dt, sizeof( DATETIME ) );
197 
198  /* Process and Thread information */
199  DosGetInfoBlocks( &ptib, &ppib );
200  addRandom( randomState, ptib );
201  addRandom( randomState, ppib );
202  addRandomData( randomState, ptib, sizeof( TIB ) ); /* TIB */
203  addRandomData( randomState, ppib, sizeof( PIB ) ); /* PIB */
204  addRandomData( randomState, ptib->tib_ptib2, sizeof( TIB2 ) ); /* TIB2 */
205 
206  /* The following are fixed for the lifetime of the process so we only
207  add them once */
208  if( !addedFixedItems )
209  {
210  /* Command line and environment strings */
211  addRandomData( randomState, ppib->pib_pchcmd,
212  strlen( ppib->pib_pchcmd ) );
213  addRandomData( randomState, ppib->pib_pchenv,
214  strlen( ppib->pib_pchenv ) );
215  addedFixedItems = TRUE;
216  }
217 
218  /* Running time information of all system threads */
219  {
220  #define PTR(ptr, ofs) ((void *) ((char *) (ptr) + (ofs)))
221  qsPtrRec_t *procstat;
222  qsPrec_t *proc;
223  qsTrec_t *thread;
224  USHORT rc,i;
225  UCHAR x;
226 
227  /* Get information about system and user time of all threads.
228  This information is changing all the time. */
229 
230  procstat = malloc (0x8000); /* Large buffer for process information */
231  rc = DosQProcStatus ( (PVOID) procstat, 0x8000); /* Query process info */
232  if (!rc) {
233  addRandom( randomState, procstat );
234  addRandomData( randomState, procstat, sizeof( qsPtrRec_t ) );
235  }
236  for ( proc = PTR( procstat->pProcRec, 0 );
237  proc -> RecType == 1;
238  proc = PTR( proc->pThrdRec, proc->cTCB * sizeof( qsTrec_t ) ) ) {
239  for ( i = 0, thread = PTR( proc->pThrdRec, 0 );
240  i < proc->cTCB;
241  i++, thread++ ) {
242  /* use low byte of (systime+usertime) */
243  x = (thread->systime + thread->usertime) & 0xFF;
244  /* but only if nonzero */
245  if( x )
246  addRandom( randomState, x );
247  }
248  }
249  free (procstat);
250  }
251 
252  /* Flush any remaining data through */
253  endRandomData( randomState, 10 );
254  }
255 
256 void slowPoll( void )
257  {
258  RANDOM_STATE randomState;
259  BYTE buffer[ RANDOM_BUFSIZE + 8 ];
260  HWND hwndParent;
261  HWND hwndNext;
262  HENUM henum;
263  BOOL fSuccess;
264  SHORT sRetLen;
265  SHORT sLength=10;
266  PID pib;
267  TID tib;
268  char pchBuffer[ 10 + 8 ];
269  RECTL rcl;
270 
271  initRandomData( randomState, buffer, RANDOM_BUFSIZE );
272 
273  /* Enumerate all PM windows */
274  hwndParent = HWND_DESKTOP;
275  henum = WinBeginEnumWindows( hwndParent );
276  while( ( hwndNext = WinGetNextWindow( henum ) ) != NULLHANDLE )
277  {
278  addRandom( randomState, hwndNext );
279 
280  WinQueryWindowProcess( hwndNext, &pib, &tib );
281  addRandomData( randomState, &tib, sizeof( TIB ) );
282  addRandomData( randomState, &pib, sizeof( PIB ) );
283  WinQueryWindowRect( hwndNext, &rcl );
284  addRandomData( randomState, &rcl, sizeof( RECTL ) );
285  }
286  fSuccess = WinEndEnumWindows( henum );
287 
288  /* Flush any remaining data through */
289  endRandomData( randomState, 50 );
290  }
291 
292 /* Get current thread ID */
293 
294 ULONG DosGetThreadID( void )
295  {
296  PTIB ptib = NULL;
297  PPIB ppib = NULL;
298 
299  /* Process and Thread information */
300  DosGetInfoBlocks( &ptib, &ppib );
301  return ppib->pib_ulpid;
302  }