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 ULONG Vector;
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188 Connected =
FALSE;
00189 Irql = Interrupt->Irql;
00190 Number = Interrupt->Number;
00191 Vector = Interrupt->Vector;
00192
if ((((Vector >= MAXIMUM_VECTOR) || (Irql >
HIGH_LEVEL) ||
00193 ((Vector <=
HIGH_LEVEL) &&
00194 ((((1 << Vector) & PCR->ReservedVectors) != 0) || (Vector != Irql))) ||
00195 (Number >=
KeNumberProcessors))) ==
FALSE) {
00196
00197
00198
00199
00200
00201
KeSetSystemAffinityThread((KAFFINITY)(1 << Number));
00202
00203
00204
00205
00206
00207
KiLockDispatcherDatabase(&OldIrql);
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
if (Interrupt->Connected ==
FALSE) {
00222
if (PCR->InterruptRoutine[Vector] ==
00223 (PKINTERRUPT_ROUTINE)(&KxUnexpectedInterrupt.DispatchCode)) {
00224 Connected =
TRUE;
00225 Interrupt->Connected =
TRUE;
00226
if (Interrupt->FloatingSave !=
FALSE) {
00227 Interrupt->DispatchAddress =
KiFloatingDispatch;
00228
00229 }
else {
00230
if (Interrupt->Irql == Interrupt->SynchronizeIrql) {
00231 Interrupt->DispatchAddress =
00232 (PKINTERRUPT_ROUTINE)
KiInterruptDispatchSame;
00233
00234 }
else {
00235 Interrupt->DispatchAddress =
00236 (PKINTERRUPT_ROUTINE)
KiInterruptDispatchRaise;
00237 }
00238 }
00239
00240
00241
00242
00243
00244
00245
00246
00247 RtlMoveMemory(Interrupt->DispatchCode,
00248 Interrupt->DispatchAddress,
00249 DISPATCH_LENGTH*4);
00250
00251 PCR->InterruptRoutine[Vector] =
00252 (PKINTERRUPT_ROUTINE)(&Interrupt->DispatchCode);
00253
00254
HalEnableSystemInterrupt(Vector, Irql, Interrupt->Mode);
00255
00256 }
else {
00257 Interruptx = CONTAINING_RECORD(PCR->InterruptRoutine[Vector],
00258
KINTERRUPT,
00259 DispatchCode[0]);
00260
00261
if (Interrupt->Mode == Interruptx->
Mode) {
00262 Connected =
TRUE;
00263 Interrupt->Connected =
TRUE;
00264
ASSERT (Irql <= KiSynchIrql);
00265
if (Interruptx->
DispatchAddress !=
KiChainedDispatch) {
00266 InitializeListHead(&Interruptx->
InterruptListEntry);
00267 Interruptx->
DispatchAddress =
KiChainedDispatch;
00268
00269 RtlMoveMemory(Interruptx->
DispatchCode,
00270 Interruptx->
DispatchAddress,
00271 DISPATCH_LENGTH*4);
00272 }
00273
00274 InsertTailList(&Interruptx->
InterruptListEntry,
00275 &Interrupt->InterruptListEntry);
00276 }
00277 }
00278 }
00279
00280
00281
00282
00283
00284
KiUnlockDispatcherDatabase(OldIrql);
00285
00286
00287
00288
00289
00290
KeRevertToUserAffinityThread();
00291 }
00292
00293
00294
00295
00296
00297
return Connected;
00298 }