+ ok_eq_long(State, 0L);
+ CheckMutex(&Mutant, 1L, FALSE, 0);
+ CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
+
+ /* Acquire recursively */
+ for (i = 0; i < 8; i++)
+ {
+ KmtStartSeh()
+ Status = KeWaitForSingleObject(&Mutant,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ KmtEndSeh(STATUS_SUCCESS);
+ ok_eq_hex(Status, STATUS_SUCCESS);
+ CheckMutex(&Mutant, -i, FALSE, 0);
+ CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
+ }
+
+ for (i = 0; i < 7; i++)
+ {
+ KmtStartSeh()
+ State = KeReleaseMutant(&Mutant, 1, FALSE, FALSE);
+ KmtEndSeh(STATUS_SUCCESS);
+ ok_eq_long(State, -7L + i);
+ CheckMutex(&Mutant, -6L + i, FALSE, 0);
+ CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
+ }
+
+ State = KeReleaseMutant(&Mutant, 1, FALSE, FALSE);
+ ok_eq_long(State, 0L);
+ CheckMutex(&Mutant, 1L, FALSE, 0);
+ CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
+
+ /* Pretend to acquire it recursively -MINLONG times */
+ KmtStartSeh()
+ Status = KeWaitForSingleObject(&Mutant,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ KmtEndSeh(STATUS_SUCCESS);
+ ok_eq_hex(Status, STATUS_SUCCESS);
+ CheckMutex(&Mutant, 0L, FALSE, 0);
+ CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
+
+ Mutant.Header.SignalState = MINLONG + 1;
+ KmtStartSeh()
+ Status = KeWaitForSingleObject(&Mutant,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ KmtEndSeh(STATUS_SUCCESS);
+ ok_eq_hex(Status, STATUS_SUCCESS);
+ CheckMutex(&Mutant, (LONG)MINLONG, FALSE, 0);
+ CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
+
+ KmtStartSeh()
+ KeWaitForSingleObject(&Mutant,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ KmtEndSeh(STATUS_MUTANT_LIMIT_EXCEEDED);
+ CheckMutex(&Mutant, (LONG)MINLONG, FALSE, 0);
+ CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
+
+ State = KeReleaseMutant(&Mutant, 1, FALSE, FALSE);
+ ok_eq_long(State, (LONG)MINLONG);
+ CheckMutex(&Mutant, (LONG)MINLONG + 1L, FALSE, 0);
+ CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
+
+ Mutant.Header.SignalState = -1;
+ State = KeReleaseMutant(&Mutant, 1, FALSE, FALSE);
+ ok_eq_long(State, -1L);
+ CheckMutex(&Mutant, 0L, FALSE, 0);
+ CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
+
+ State = KeReleaseMutant(&Mutant, 1, FALSE, FALSE);
+ ok_eq_long(State, 0L);
+ CheckMutex(&Mutant, 1L, FALSE, 0);
+ CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
+
+ /* Now release it once too often */
+ KmtStartSeh()
+ KeReleaseMutant(&Mutant, 1, FALSE, FALSE);
+ KmtEndSeh(STATUS_MUTANT_NOT_OWNED);
+ CheckMutex(&Mutant, 1L, FALSE, 0);