00147 :
00148
00149 This function connects an interrupt object to
the interrupt vector
00150 specified by
the interrupt object. If
the interrupt object
is already
00151 connected, or an attempt
is made to connect to an interrupt that cannot
00152 be connected, then a value of
FALSE is returned. Else
the specified
00153 interrupt object
is connected to
the interrupt vector,
the connected
00154 state
is set to
TRUE, and
TRUE is returned as
the function value.
00155
00156 Arguments:
00157
00158 Interrupt - Supplies a pointer to a
control object of
type interrupt.
00159
00160 Return Value:
00161
00162 If
the interrupt object
is already connected or an attempt
is made to
00163 connect to an interrupt vector that cannot be connected, then a value
00164 of
FALSE is returned. Else a value of
TRUE is returned.
00165
00166 --*/
00167
00168 {
00169
00170 BOOLEAN Connected;
00171
PKINTERRUPT Interruptx;
00172 KIRQL Irql;
00173
CHAR Number;
00174 KIRQL OldIrql;
00175 KIRQL PreviousIrql;
00176 ULONG Vector;
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189 Connected =
FALSE;
00190 Irql = Interrupt->Irql;
00191 Number = Interrupt->Number;
00192 Vector = Interrupt->Vector;
00193
if (
00194 (Vector < MAXIMUM_VECTOR) &&
00195 (Irql <=
HIGH_LEVEL) &&
00196 (Number <
KeNumberProcessors) &&
00197 (
00198 (Vector >
HIGH_LEVEL) ||
00199 ((PCR->ReservedVectors & (1 << Vector)) == 0)
00200 )
00201 ) {
00202
00203
00204
00205
00206
00207
00208
KeSetSystemAffinityThread((KAFFINITY)(1 << Number));
00209
00210
00211
00212
00213
00214
KiLockDispatcherDatabase(&OldIrql);
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
if (Interrupt->Connected ==
FALSE) {
00229
if (PCR->InterruptRoutine[Vector] ==
00230 (PKINTERRUPT_ROUTINE)(&KxUnexpectedInterrupt.DispatchCode)) {
00231 Connected =
TRUE;
00232 Interrupt->Connected =
TRUE;
00233
if (Interrupt->FloatingSave) {
00234 Interrupt->DispatchAddress =
KiFloatingDispatch;
00235
00236 }
else {
00237
if (Interrupt->Irql == Interrupt->SynchronizeIrql) {
00238
#if defined(NT_UP)
00239
Interrupt->DispatchAddress =
00240 (PKINTERRUPT_ROUTINE)Interrupt->ServiceRoutine;
00241
#else
00242
Interrupt->DispatchAddress =
00243 (PKINTERRUPT_ROUTINE)
KiInterruptDispatchSame;
00244
#endif
00245
00246 }
else {
00247 Interrupt->DispatchAddress =
00248 (PKINTERRUPT_ROUTINE)
KiInterruptDispatchRaise;
00249 }
00250 }
00251
00252
00253
00254
00255
00256
00257
00258 Interrupt->DispatchCode[0] =
00259 *(PULONG)(Interrupt->DispatchAddress);
00260 Interrupt->DispatchCode[1] =
00261 *(((PULONG)(Interrupt->DispatchAddress))+1);
00262 PCR->InterruptRoutine[Vector] =
00263 (PKINTERRUPT_ROUTINE)Interrupt->DispatchCode;
00264
00265
HalEnableSystemInterrupt(Vector, Irql, Interrupt->Mode);
00266
00267 }
else if (Interrupt->ShareVector) {
00268 Interruptx = CONTAINING_RECORD(PCR->InterruptRoutine[Vector],
00269
KINTERRUPT,
00270 DispatchCode[0]);
00271
if (Interruptx->
ShareVector &&
00272 Interrupt->Mode == Interruptx->
Mode) {
00273 Connected =
TRUE;
00274 Interrupt->Connected =
TRUE;
00275
KeRaiseIrql((KIRQL)(
max(Irql, SYNCH_LEVEL)), &PreviousIrql);
00276
if (Interruptx->
DispatchAddress !=
00277 (PKINTERRUPT_ROUTINE)
KiChainedDispatch) {
00278 InitializeListHead(&Interruptx->
InterruptListEntry);
00279 Interruptx->
DispatchAddress =
00280 (PKINTERRUPT_ROUTINE)
KiChainedDispatch;
00281 Interruptx->
DispatchCode[0] =
00282 *(PULONG)
KiChainedDispatch;
00283 Interruptx->
DispatchCode[1] =
00284 *(((PULONG)
KiChainedDispatch)+1);
00285 }
00286
00287 InsertTailList(&Interruptx->
InterruptListEntry,
00288 &Interrupt->InterruptListEntry);
00289
KeLowerIrql(PreviousIrql);
00290 }
00291 }
00292 }
00293
00294
00295
00296
00297
00298
KiUnlockDispatcherDatabase(OldIrql);
00299
00300
00301
00302
00303
00304
KeRevertToUserAffinityThread();
00305 }
00306
00307
00308
00309
00310
00311
return Connected;
00312 }