NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pUnicodeString) { UNICODE_STRING ntDeviceName; UNICODE_STRING dosDeviceName; ULONG i; NTSTATUS status = STATUS_SUCCESS; gsfmSysFreezerDriverObject = pDriverObject; #ifdef DBG //pDriverObject->DriverUnload = DriverUnload; #endif for(i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; ++i) { pDriverObject->MajorFunction[i] = SSFPassThrough; } pDriverObject->FastIoDispatch = &gFastIoDispatch; // Создадим объект устройства для общения с нашим драйвером RtlInitUnicodeString(&ntDeviceName, NT_DEVICE_NAME); RtlInitUnicodeString(&dosDeviceName, DOS_DEVICE_NAME); status = IoCreateDevice(pDriverObject, sizeof(SYS_FREEZER_DEVICE_EXTENSTION), &ntDeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &gGuiDevice); if(!NT_SUCCESS(status)) { DBG_PRINT_ERR(L"Cannot create gui device"); return status; } ((PSYS_FREEZER_DEVICE_EXTENSION)gGuiDevice->DeviceExtension)->Type = GUIINTERFACE; status = IoCreateSymbolicLink(&dosDeviceName, &ntDeviceName); if(!NT_SUCCESS(status)) { DBG_PRINT_ERR(L"cannot create symbolic link"); IoDeleteDevice(&gGuiDevice); return status; } for(i = 0; i < 26; ++i) { gDriveHookDevices[i] = NULL; } HookDriveSet(4, gsfmSysFreezerDriverObject); return STATUS_SUCCESS; }
static void after_shutdown_cb(uv_shutdown_t* req, int status) { /*assert(status == 0);*/ if (status < 0) DBG_PRINT_ERR("err: %s\n", uv_strerror(status)); uv_close((uv_handle_t*)req->handle, on_close_cb); free(req); }
static void after_write_cb(uv_write_t* req, int status) { write_req_t * wr = (write_req_t*)req; DBG_PRINT("%s: wr: %p buf->base: %p\n", __FUNCTION__, wr, wr->buf.base); if (wr->buf.base != NULL) free(wr->buf.base); free(wr); if (status == 0) return; DBG_PRINT_ERR("uv_write : %s\n", uv_strerror(status)); if (status == UV_ECANCELED) return; assert(status == UV_EPIPE); uv_close((uv_handle_t*)req->handle, on_close_cb); }
int db_delete(db_handle_t *db, uint64_t cardid) { int returnVal = 0; if ( NULL == db) { // This should not happen. So warn and return error DBG_PRINT(DBG_WARN, ("Db handle is NULL")); returnVal = HANDLE_NULL_ERROR; goto DEL_ERROR; } // if ( NULL == db ) #ifdef SQL_LITE char sql[BUF_SIZE]; char *errMsg; int counter = 0; memset(sql, 0, BUF_SIZE); #ifdef ALLOW_DUPLICATES sprintf(sql, "SELECT * FROM %s WHERE id = %llu LIMIT 1", TABLE_NAME, cardid); #else sprintf(sql, "SELECT * FROM %s WHERE id = %llu", TABLE_NAME, cardid); #endif returnVal = sqlite3_exec(db->handle, sql, callback, (void *)&counter, &errMsg); if ( returnVal ) { DBG_PRINT(DBG_WARN, ("Error While Searching id = %lld. %s", cardid, errMsg)); sqlite3_free(errMsg); returnVal = FIND_ERROR; goto DEL_ERROR; } // if ( returnVal ) if ( counter == 0 ) { DBG_PRINT(DBG_WARN, ("Card id = %llu Not Found in Our Database", cardid)); returnVal = ELE_NOT_FOUND_ERROR; goto DEL_ERROR; } else { memset(sql, 0, BUF_SIZE); sprintf(sql, "DELETE FROM %s WHERE id = %llu LIMIT 1", TABLE_NAME, cardid); returnVal = sqlite3_exec(db->handle, sql, NULL, 0, &errMsg); if ( returnVal ) { DBG_PRINT(DBG_WARN, ("Error While Deleting id = %llu. %s", cardid, errMsg)); sqlite3_free(errMsg); returnVal = DELETE_ERROR; goto DEL_ERROR; } // if ( returnVal ) } // if ( counter == 0) #else returnVal = db_find(db, cardid); if ( returnVal != 0 ) { DBG_PRINT(DBG_WARN, ("Card id %llu Do Not Exists in Our Database")); return ELE_NOT_FOUND_ERROR; } uint64_t id = 0ULL; uint64_t prevId = 0ULL; long left = -1L; long right = -1L; long curPos = -1L; int totlen = sizeof(id) + sizeof(left) + sizeof(right); fseek(db->handle, (long)-totlen, SEEK_CUR); // Move to the begining of record. returnVal = fread(&id, sizeof(id), 1, db->handle); returnVal = fread(&left, sizeof(left), 1, db->handle); returnVal = fread(&right, sizeof(right), 1, db->handle); if ( -1L == left && -1L == right) { // Node is leaf. curPos = ftell(db->handle) - ((long) (sizeof(uint64_t) + 2 * sizeof(long))); if ( 0L == curPos ) { // only one node in the tree. Truncate the file. fclose(db->handle); db->handle = fopen(db->fileName, "wb"); // reopen in write mode. It will truncate it. returnVal = 0; goto DEL_ERROR; } // Delete the link fseek(db->handle, prevPos, SEEK_SET); fread(&prevId, sizeof(prevId), 1, db->handle); if ( prevId < id ) { fseek(db->handle, prevPos + sizeof(left) + sizeof(prevId), SEEK_SET); returnVal = fwrite(&right, sizeof(right), 1, db->handle); } else { returnVal = fwrite(&left, sizeof(left), 1, db->handle); } if ( 1 != returnVal ) { DBG_PRINT_ERR(("Something bad Happened\n Database Corrupted. Sorry !!")); perror(NULL); returnVal = DB_CORRUPT_ERROR; goto DEL_ERROR; } fflush(db->handle); // Delete the node. fseek(db->handle, curPos, SEEK_SET); id = -1ULL; returnVal = fwrite(&id, sizeof(id), 1, db->handle); if ( 1 != returnVal ) { DBG_PRINT_ERR(("Something bad Happened\n Database Corrupted. Sorry !!")); returnVal = DB_CORRUPT_ERROR; goto DEL_ERROR; } fflush(db->handle); return 0; } if ( -1L == left || -1L == right ) { //Node with one child if ( -1L == left ) { curPos = ftell(db->handle) - ((long) (sizeof(uint64_t) + 2 * sizeof(long))); fseek(db->handle, right, SEEK_SET); fread(&id, sizeof(id), 1, db->handle); fread(&left, sizeof(left), 1, db->handle); fread(&right, sizeof(right), 1, db->handle); fseek(db->handle, curPos, SEEK_SET); returnVal = fwrite(&id, sizeof(id), 1, db->handle); if ( 1 != returnVal ) { DBG_PRINT_ERR(("Something bad Happened\n Database Corrupted. Sorry !!")); returnVal = DB_CORRUPT_ERROR; goto DEL_ERROR; } returnVal = fwrite(&left, sizeof(left), 1, db->handle); if ( 1 != returnVal ) { DBG_PRINT_ERR(("Something bad Happened\n Database Corrupted. Sorry !!")); returnVal = DB_CORRUPT_ERROR; goto DEL_ERROR; } returnVal = fwrite(&right, sizeof(right), 1, db->handle); if ( 1 != returnVal ) { DBG_PRINT_ERR(("Something bad Happened\n Database Corrupted. Sorry !!")); returnVal = DB_CORRUPT_ERROR; goto DEL_ERROR; } fflush(db->handle); return 0; } // if ( -1L == left ) if ( -1L == right ) { curPos = ftell(db->handle) - ((long) (sizeof(uint64_t) + 2 * sizeof(long))); fseek(db->handle, left, SEEK_SET); fread(&id, sizeof(id), 1, db->handle); fread(&left, sizeof(left), 1, db->handle); fread(&right, sizeof(right), 1, db->handle); fseek(db->handle, curPos, SEEK_SET); returnVal = fwrite(&id, sizeof(id), 1, db->handle); if ( 1 != returnVal ) { DBG_PRINT_ERR(("Something bad Happened\n Database Corrupted. Sorry !!")); returnVal = DB_CORRUPT_ERROR; goto DEL_ERROR; } returnVal = fwrite(&left, sizeof(left), 1, db->handle); if ( 1 != returnVal ) { DBG_PRINT_ERR(("Something bad Happened\n Database Corrupted. Sorry !!")); returnVal = DB_CORRUPT_ERROR; goto DEL_ERROR; } returnVal = fwrite(&right, sizeof(right), 1, db->handle); if ( 1 != returnVal ) { DBG_PRINT_ERR(("Something bad Happened\n Database Corrupted. Sorry !!")); returnVal = DB_CORRUPT_ERROR; goto DEL_ERROR; } fflush(db->handle); return 0; } // if ( -1L == left ) } // if ( -1L == left || -1L == right ) // go to the left child and keep on going right untill you see an // node with no right child. curPos = ftell(db->handle) - ((long) (sizeof(uint64_t) + 2 * sizeof(long))); long parentPos = curPos; // go to left. fseek(db->handle, left, SEEK_SET); long temp = -1L; while ( 1 ) { // Keep on going right. fread(&id, sizeof(id), 1, db->handle); fread(&left, sizeof(left), 1, db->handle); fread(&right, sizeof(right), 1, db->handle); temp = ftell(db->handle) - ((long) sizeof(uint64_t) + 2 * sizeof(long)); if ( -1L == right ) break; parentPos = temp; fseek(db->handle, right, SEEK_SET); } long deletedPos = ftell(db->handle) - ((long) sizeof(uint64_t) + 2 * sizeof(long)); uint64_t replacementValue = id; // delete the node. if ( left == -1L && right == -1L ) { fseek(db->handle, deletedPos, SEEK_SET); fread(&id, sizeof(id), 1, db->handle); fseek(db->handle, parentPos, SEEK_SET); uint64_t parentId = -1ULL; fread(&parentId, sizeof(parentId), 1, db->handle); if ( parentId > id ) { fwrite(&left, sizeof(left), 1, db->handle); } else { fseek(db->handle, sizeof(left), SEEK_CUR); fwrite(&right, sizeof(right), 1, db->handle); } fseek(db->handle, deletedPos, SEEK_SET); id = -1ULL; returnVal = fwrite( &id, sizeof(id), 1, db->handle); if ( 1 != returnVal ) { DBG_PRINT_ERR(("Something bad Happened\n Database Corrupted. Sorry !!")); returnVal = DB_CORRUPT_ERROR; goto DEL_ERROR; } fflush(db->handle); fseek(db->handle, (long)(temp + sizeof(id) + sizeof(left)), SEEK_SET); right = -1L; returnVal = fwrite(&right, sizeof(right), 1, db->handle); if ( 1 != returnVal ) { DBG_PRINT_ERR(("Something bad Happened\n Database Corrupted. Sorry !!")); returnVal = DB_CORRUPT_ERROR; goto DEL_ERROR; } fflush(db->handle); // Replace the node. fseek(db->handle, curPos, SEEK_SET); returnVal = fwrite(&replacementValue, sizeof(replacementValue), 1, db->handle); if ( 1 != returnVal ) { DBG_PRINT_ERR(("Something bad Happened\n Database Corrupted. Sorry !!")); returnVal = DB_CORRUPT_ERROR; goto DEL_ERROR; } fflush(db->handle); return 0; } else { fseek(db->handle, curPos, SEEK_SET); returnVal = fwrite(&replacementValue, sizeof(replacementValue), 1, db->handle); if ( 1 != returnVal ) { DBG_PRINT_ERR(("Something bad Happened\n Database Corrupted. Sorry !!")); returnVal = DB_CORRUPT_ERROR; goto DEL_ERROR; } fflush(db->handle); fseek(db->handle, left, SEEK_SET); fread(&id, sizeof(id), 1, db->handle); fread(&left, sizeof(left), 1, db->handle); fread(&right, sizeof(right), 1, db->handle); fseek(db->handle, deletedPos, SEEK_SET); returnVal = fwrite(&id, sizeof(id), 1, db->handle); if ( 1 != returnVal ) { DBG_PRINT_ERR(("Something bad Happened\n Database Corrupted. Sorry !!")); returnVal = DB_CORRUPT_ERROR; goto DEL_ERROR; } returnVal = fwrite(&left, sizeof(left), 1, db->handle); if ( 1 != returnVal ) { DBG_PRINT_ERR(("Something bad Happened\n Database Corrupted. Sorry !!")); returnVal = DB_CORRUPT_ERROR; goto DEL_ERROR; } returnVal = fwrite(&right, sizeof(right), 1, db->handle); if ( 1 != returnVal ) { DBG_PRINT_ERR(("Something bad Happened\n Database Corrupted. Sorry !!")); returnVal = DB_CORRUPT_ERROR; goto DEL_ERROR; } fflush(db->handle); return 0; } #endif // SQL_LITE DEL_ERROR: return returnVal; }
int db_insert(db_handle_t *db, uint64_t id) { int returnVal = 0; if ( NULL == db ) { // This should not happen. So warn and return error DBG_PRINT(DBG_WARN, ("Db handle is NULL")); returnVal = HANDLE_NULL_ERROR; goto INSERT_ERR; } #ifdef SQL_LITE char sql[BUF_SIZE]; char *errMsg; memset(sql, 0, BUF_SIZE); sprintf(sql, "INSERT INTO %s ( id ) VALUES ( %llu )", TABLE_NAME, id); returnVal = sqlite3_exec(db->handle, sql, NULL, 0, &errMsg); if ( returnVal ) { DBG_PRINT(DBG_WARN, ("Error While Inserting id = %lld. %s", id, errMsg)); sqlite3_free(errMsg); returnVal = INSERT_INTO_ERROR; goto INSERT_ERR; } #else // Start From Begining. long left = -1L; long right = -1L; fseek(db->handle, 0L, SEEK_END); if ( 0L == ftell(db->handle )) { // This is the first entry. returnVal = fwrite(&id, sizeof(id), 1, db->handle); if ( 1 != returnVal ) { DBG_PRINT_ERR(("Something bad Happened\n Database Corrupted. Sorry !!")); returnVal = DB_CORRUPT_ERROR; goto INSERT_ERR; } returnVal = fwrite(&left, sizeof(left), 1, db->handle); if ( 1 != returnVal ) { DBG_PRINT_ERR(("Something bad Happened\n Database Corrupted. Sorry !!")); returnVal = DB_CORRUPT_ERROR; goto INSERT_ERR; } returnVal = fwrite(&right, sizeof(right), 1, db->handle); if ( 1 != returnVal ) { DBG_PRINT_ERR(("Something bad Happened\n Database Corrupted. Sorry !!")); returnVal = DB_CORRUPT_ERROR; goto INSERT_ERR; } fflush(db->handle); returnVal = 0; goto INSERT_ERR; } // Go to Begining. fseek(db->handle, 0L, SEEK_SET); returnVal = traverse(db->handle, id); if ( returnVal != 0 ) goto INSERT_ERR; long totLen = sizeof(id) + sizeof(left) + sizeof(right); totLen = -totLen; uint64_t curid = 0ULL; // go back totLen bytes in file fseek(db->handle, totLen, SEEK_CUR); long curPos = ftell(db->handle); fread(&curid, sizeof(id), 1, db->handle); totLen = -totLen; if ( id < curid ) { curPos += sizeof(curid); } else { curPos += (sizeof(curid) + sizeof(left)); } // Go to the end to insert new value fseek(db->handle, 0L, SEEK_END); returnVal = fwrite(&id, sizeof(id), 1, db->handle); if ( 1 != returnVal ) { DBG_PRINT_ERR(("Something bad Happened\n Database Corrupted. Sorry !!")); returnVal = DB_CORRUPT_ERROR; goto INSERT_ERR; } returnVal = fwrite(&left, sizeof(left), 1, db->handle); if ( 1 != returnVal ) { DBG_PRINT_ERR(("Something bad Happened\n Database Corrupted. Sorry !!")); returnVal = DB_CORRUPT_ERROR; goto INSERT_ERR; } returnVal = fwrite(&left, sizeof(left), 1, db->handle); if ( 1 != returnVal ) { DBG_PRINT_ERR(("Something bad Happened\n Database Corrupted. Sorry !!")); returnVal = DB_CORRUPT_ERROR; goto INSERT_ERR; } fflush(db->handle); long curPos2 = ftell(db->handle); curPos2 -= totLen; // Store new inserted postion. fseek(db->handle, curPos, SEEK_SET); returnVal = fwrite(&curPos2, sizeof(curPos2), 1, db->handle); if ( 1 != returnVal ) { DBG_PRINT_ERR(("Something bad Happened\n Database Corrupted. Sorry !!")); returnVal = DB_CORRUPT_ERROR; goto INSERT_ERR; } return 0; #endif INSERT_ERR: return returnVal; } // end of db_insert
BOOLEAN HookDrive(IN ULONG drive, IN PDRIVER_OBJECT driverObject) { IO_STATUS_BLOCK ioStatus; HANDLE ntFileHandle; OBJECT_ATTRIBUTES objectAttributes; PDEVICE_OBJECT fileSysDevice; PDEVICE_OBJECT hookDevice; UNICODE_STRING fileNameUnicodeString; ULONG fileFsAttributesSize; WCHAR fileName[] = L"\\DosDevices\\A:\\"; NTSTATUS ntStatus; ULONG i; PFILE_OBJECT fileObject; PSYS_FREEZER_DEVICE_EXTENSION devExt; if(drive >= 26) { return FALSE; } if(gDriveHookDevices[drive] == NULL) { fileName[12] = (CHAR)('A' + drive); RtlInitUnicodeString(&fileNameUnicodeString, fileName); InitializeObjectAttributes(&objectAttributes, &fileNameUnicodeString, OBJ_CASE_INSENSITIVE, NULL, NULL); ntStatus = ZwCreateFile(&ntFileHandle, SYNCHRONIZE | FILE_ANY_ACCESS, &objectAttributes, &ioStatus, NULL, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE, NULL, 0); if(!NT_SUCCESS(ntStatus)) { DBG_PRINT_ERR(L"Could open drive"); return FALSE; } DBG_PRINT_INFO(L"opened root directory"); ntStatus = ObReferenceObjectByHandle(ntFileHandle, FILE_READ_DATA, NULL, KernelMode, &fileObject, NULL); if(!NT_SUCCESS(ntStatus)) { DBG_PRINT_ERR(L"Could not get object by handle"); ZwClose(ntFileHandle); return FALSE; } fileSysDevice = IoGetRelatedDeviceObject(fileObject); if(!fileSysDevice) { DBG_PRINT_ERR(L"Could not get related device object"); ObDereferenceObject(fileObject); ZwClose(ntFileHandle); return FALSE; } for(i = 0; i < 26; ++i) { if(gDriveHookDevices[i] == fileSysDevice) { ObDereferenceObject(fileObject); ZwClose(ntFileHandle); gDriveHookDevices[drive] = fileSysDevice; return TRUE; } } ntStatus = IoCreateDevice(driverObject, sizeof(SYS_FREEZER_DEVICE_EXTENSTION), NULL, fileSysDevice->DeviceType, 0, FALSE, &hookDevice); if(!NT_SUCCESS(ntStatus)) { DBG_PRINT_ERR(L"Failed: to create associated device"); ObDereferenceObject(fileObject); ZwClose(ntFileHandle); return FALSE; } hookDevice->Flags &= ~DO_DEVICE_INITIALIZING; devExt = hookDevice->DeviceExtension; devExt->AttachedToDeviceObject = fileSysDevice; devExt->DriveLetter = (CHAR)('A' + drive); devExt->Hooked = TRUE; devExt->Type = STANDART; ntStatus = IoAttachDeviceByPointer(hookDevice, fileSysDevice); if(!NT_SUCCESS(ntStatus)) { DBG_PRINT_ERR(L"Failed: attaching to device"); //IoDeleteDevice(hookDevice); ObDereferenceObject(fileObject); ZwClose(ntFileHandle); return FALSE; } else { DBG_PRINT_INFO(L"Successfully connected to file system device"); } ObDereferenceObject(fileObject); ZwClose(ntFileHandle); gDriveHookDevices[drive] = hookDevice; } else { devExt = gDriveHookDevices[drive]->DeviceExtension; devExt->Hooked = TRUE; } return TRUE; }