OSDN Git Service

If there is hunged process, injection thread stall and when hunged process restart...
[yamy/yamy.git] / d / keyque.c
1 ///////////////////////////////////////////////////////////////////////////////\r
2 // keyque.c\r
3 \r
4 \r
5 ///////////////////////////////////////////////////////////////////////////////\r
6 // Definitions\r
7 \r
8 \r
9 typedef struct KeyQue {\r
10         ULONG count;                    // Number of keys in the que\r
11         ULONG lengthof_que;             // Length of que\r
12         KEYBOARD_INPUT_DATA *insert;    // Insertion pointer for que\r
13         KEYBOARD_INPUT_DATA *remove;    // Removal pointer for que\r
14         KEYBOARD_INPUT_DATA *que;\r
15 } KeyQue;\r
16 \r
17 \r
18 #define KeyQueSize 100\r
19 \r
20 \r
21 ///////////////////////////////////////////////////////////////////////////////\r
22 // Prototypes\r
23 \r
24 \r
25 NTSTATUS KqInitialize(KeyQue *kq);\r
26 void KqClear(KeyQue *kq);\r
27 NTSTATUS KqFinalize(KeyQue *kq);\r
28 BOOLEAN KqIsEmpty(KeyQue *kq);\r
29 ULONG KqEnque(KeyQue *kq, IN  KEYBOARD_INPUT_DATA *buf, IN ULONG lengthof_buf);\r
30 ULONG KqDeque(KeyQue *kq, OUT KEYBOARD_INPUT_DATA *buf, IN ULONG lengthof_buf);\r
31 \r
32 \r
33 #ifdef ALLOC_PRAGMA\r
34 #pragma alloc_text( init, KqInitialize )\r
35 #pragma alloc_text( page, KqFinalize )\r
36 #endif // ALLOC_PRAGMA\r
37 \r
38 \r
39 ///////////////////////////////////////////////////////////////////////////////\r
40 // Functions\r
41 \r
42 \r
43 NTSTATUS KqInitialize(KeyQue *kq)\r
44 {\r
45         kq->count = 0;\r
46         kq->lengthof_que = KeyQueSize;\r
47         kq->que = ExAllocatePool(NonPagedPool,\r
48                                                          kq->lengthof_que * sizeof(KEYBOARD_INPUT_DATA));\r
49         kq->insert = kq->que;\r
50         kq->remove = kq->que;\r
51         if (kq->que == NULL)\r
52                 return STATUS_INSUFFICIENT_RESOURCES;\r
53         else\r
54                 return STATUS_SUCCESS;\r
55 }\r
56 \r
57 \r
58 void KqClear(KeyQue *kq)\r
59 {\r
60         kq->count = 0;\r
61         kq->insert = kq->que;\r
62         kq->remove = kq->que;\r
63 }\r
64 \r
65 \r
66 NTSTATUS KqFinalize(KeyQue *kq)\r
67 {\r
68         if (kq->que)\r
69                 ExFreePool(kq->que);\r
70         return STATUS_SUCCESS;\r
71 }\r
72 \r
73 \r
74 BOOLEAN KqIsEmpty(KeyQue *kq)\r
75 {\r
76         return 0 == kq->count;\r
77 }\r
78 \r
79 \r
80 // return: lengthof copied data\r
81 ULONG KqEnque(KeyQue *kq, IN KEYBOARD_INPUT_DATA *buf, IN ULONG lengthof_buf)\r
82 {\r
83         ULONG rest;\r
84 \r
85         if (kq->lengthof_que - kq->count < lengthof_buf) // overflow\r
86                 lengthof_buf = kq->lengthof_que - kq->count; // chop overflowed datum\r
87         if (lengthof_buf <= 0)\r
88                 return 0;\r
89 \r
90         rest = kq->lengthof_que - (kq->insert - kq->que);\r
91         if (rest < lengthof_buf) {\r
92                 ULONG copy = rest;\r
93                 if (0 < copy) {\r
94                         RtlMoveMemory((PCHAR)kq->insert, (PCHAR)buf,\r
95                                                   sizeof(KEYBOARD_INPUT_DATA) * copy);\r
96                         buf += copy;\r
97                 }\r
98                 copy = lengthof_buf - copy;\r
99                 if (0 < copy)\r
100                         RtlMoveMemory((PCHAR)kq->que, (PCHAR)buf,\r
101                                                   sizeof(KEYBOARD_INPUT_DATA) * copy);\r
102                 kq->insert = kq->que + copy;\r
103         } else {\r
104                 RtlMoveMemory((PCHAR)kq->insert, (PCHAR)buf,\r
105                                           sizeof(KEYBOARD_INPUT_DATA) * lengthof_buf);\r
106                 kq->insert += lengthof_buf;\r
107         }\r
108         kq->count += lengthof_buf;\r
109         return lengthof_buf;\r
110 }\r
111 \r
112 \r
113 // return: lengthof copied data\r
114 ULONG KqDeque(KeyQue *kq, OUT KEYBOARD_INPUT_DATA *buf, IN ULONG lengthof_buf)\r
115 {\r
116         ULONG rest;\r
117 \r
118         if (kq->count < lengthof_buf)\r
119                 lengthof_buf = kq->count;\r
120         if (lengthof_buf <= 0)\r
121                 return 0;\r
122 \r
123         rest = kq->lengthof_que - (kq->remove - kq->que);\r
124         if (rest < lengthof_buf) {\r
125                 ULONG copy = rest;\r
126                 if (0 < copy) {\r
127                         RtlMoveMemory((PCHAR)buf, (PCHAR)kq->remove,\r
128                                                   sizeof(KEYBOARD_INPUT_DATA) * copy);\r
129                         buf += copy;\r
130                 }\r
131                 copy = lengthof_buf - copy;\r
132                 if (0 < copy)\r
133                         RtlMoveMemory((PCHAR)buf, (PCHAR)kq->que,\r
134                                                   sizeof(KEYBOARD_INPUT_DATA) * copy);\r
135                 kq->remove = kq->que + copy;\r
136         } else {\r
137                 RtlMoveMemory((PCHAR)buf, (PCHAR)kq->remove,\r
138                                           sizeof(KEYBOARD_INPUT_DATA) * lengthof_buf);\r
139                 kq->remove += lengthof_buf;\r
140         }\r
141         kq->count -= lengthof_buf;\r
142         return lengthof_buf;\r
143 }\r