NTSTATUS LwNtReadDirectoryChangeFile( IN IO_FILE_HANDLE FileHandle, IN OUT OPTIONAL PIO_ASYNC_CONTROL_BLOCK AsyncControlBlock, OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID Buffer, IN ULONG Length, IN BOOLEAN WatchTree, IN FILE_NOTIFY_CHANGE NotifyFilter, IN OPTIONAL PULONG MaxBufferSize ) { NTSTATUS status = 0; int EE = 0; const LWMsgTag requestType = NT_IPC_MESSAGE_TYPE_READ_DIRECTORY_CHANGE_FILE; const LWMsgTag responseType = NT_IPC_MESSAGE_TYPE_READ_DIRECTORY_CHANGE_FILE_RESULT; NT_IPC_MESSAGE_READ_DIRECTORY_CHANGE_FILE request = { 0 }; PNT_IPC_MESSAGE_GENERIC_FILE_BUFFER_RESULT pResponse = NULL; PVOID pReply = NULL; IO_STATUS_BLOCK ioStatusBlock = { 0 }; LWMsgCall* pCall = NULL; status = LwIoConnectionAcquireCall(&pCall); GOTO_CLEANUP_ON_STATUS_EE(status, EE); if (AsyncControlBlock) { status = STATUS_INVALID_PARAMETER; GOTO_CLEANUP_EE(EE); } request.FileHandle = FileHandle; request.Length = Length; request.WatchTree = WatchTree; request.NotifyFilter = NotifyFilter; request.MaxBufferSize = MaxBufferSize; status = NtpCtxCall(pCall, requestType, &request, responseType, &pReply); ioStatusBlock.Status = status; GOTO_CLEANUP_ON_STATUS_EE(status, EE); pResponse = (PNT_IPC_MESSAGE_GENERIC_FILE_BUFFER_RESULT) pReply; status = NtpCtxGetBufferResult(&ioStatusBlock, Buffer, Length, pResponse); GOTO_CLEANUP_ON_STATUS_EE(status, EE); cleanup: if (pCall) { NtpCtxFreeResponse(pCall, responseType, pResponse); lwmsg_call_release(pCall); } *IoStatusBlock = ioStatusBlock; LOG_LEAVE_IF_STATUS_EE(status, EE); return status; }
NTSTATUS LwNtLockFile( IN IO_FILE_HANDLE FileHandle, IN OUT OPTIONAL PIO_ASYNC_CONTROL_BLOCK AsyncControlBlock, OUT PIO_STATUS_BLOCK IoStatusBlock, IN LONG64 ByteOffset, IN LONG64 Length, IN ULONG Key, IN BOOLEAN FailImmediately, IN BOOLEAN ExclusiveLock ) { NTSTATUS status = 0; int EE = 0; const LWMsgTag requestType = NT_IPC_MESSAGE_TYPE_LOCK_FILE; const LWMsgTag responseType = NT_IPC_MESSAGE_TYPE_LOCK_FILE_RESULT; NT_IPC_MESSAGE_LOCK_FILE request = { 0 }; PNT_IPC_MESSAGE_GENERIC_FILE_IO_RESULT pResponse = NULL; PVOID pReply = NULL; IO_STATUS_BLOCK ioStatusBlock = { 0 }; LWMsgCall* pCall = NULL; status = LwIoConnectionAcquireCall(&pCall); GOTO_CLEANUP_ON_STATUS_EE(status, EE); if (AsyncControlBlock) { status = STATUS_INVALID_PARAMETER; GOTO_CLEANUP_EE(EE); } request.FileHandle = FileHandle; request.ByteOffset = ByteOffset, request.Length = Length; request.Key = Key; request.FailImmediately = FailImmediately; request.ExclusiveLock = ExclusiveLock; status = NtpCtxCall(pCall, requestType, &request, responseType, &pReply); ioStatusBlock.Status = status; GOTO_CLEANUP_ON_STATUS_EE(status, EE); pResponse = (PNT_IPC_MESSAGE_GENERIC_FILE_IO_RESULT) pReply; status = NtpCtxGetIoResult(&ioStatusBlock, pResponse); GOTO_CLEANUP_ON_STATUS_EE(status, EE); cleanup: if (pCall) { NtpCtxFreeResponse(pCall, responseType, pResponse); lwmsg_call_release(pCall); } *IoStatusBlock = ioStatusBlock; LOG_LEAVE_IF_STATUS_EE(status, EE); return status; }
NTSTATUS LwNtQueryDirectoryFile( IN IO_FILE_HANDLE FileHandle, IN OUT OPTIONAL PIO_ASYNC_CONTROL_BLOCK AsyncControlBlock, OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID FileInformation, IN ULONG Length, IN FILE_INFORMATION_CLASS FileInformationClass, IN BOOLEAN ReturnSingleEntry, IN OPTIONAL PIO_MATCH_FILE_SPEC FileSpec, IN BOOLEAN RestartScan ) { NTSTATUS status = 0; int EE = 0; const LWMsgTag requestType = NT_IPC_MESSAGE_TYPE_QUERY_DIRECTORY_FILE; const LWMsgTag responseType = NT_IPC_MESSAGE_TYPE_QUERY_DIRECTORY_FILE_RESULT; NT_IPC_MESSAGE_QUERY_DIRECTORY_FILE request = { 0 }; PNT_IPC_MESSAGE_GENERIC_FILE_BUFFER_RESULT pResponse = NULL; PVOID pReply = NULL; IO_STATUS_BLOCK ioStatusBlock = { 0 }; LWMsgCall* pCall = NULL; status = LwIoConnectionAcquireCall(&pCall); GOTO_CLEANUP_ON_STATUS_EE(status, EE); if (AsyncControlBlock) { status = STATUS_INVALID_PARAMETER; GOTO_CLEANUP_EE(EE); } request.FileHandle = FileHandle; request.Length = Length; request.FileInformationClass = FileInformationClass; request.ReturnSingleEntry = ReturnSingleEntry; request.FileSpec = FileSpec; request.RestartScan = RestartScan; status = NtpCtxCall(pCall, requestType, &request, responseType, &pReply); ioStatusBlock.Status = status; GOTO_CLEANUP_ON_STATUS_EE(status, EE); pResponse = (PNT_IPC_MESSAGE_GENERIC_FILE_BUFFER_RESULT) pReply; status = NtpCtxGetBufferResult(&ioStatusBlock, FileInformation, Length, pResponse); GOTO_CLEANUP_ON_STATUS_EE(status, EE); cleanup: if (pCall) { NtpCtxFreeResponse(pCall, responseType, pResponse); lwmsg_call_release(pCall); } *IoStatusBlock = ioStatusBlock; LOG_LEAVE_IF_STATUS_EE(status, EE); return status; }
DWORD LwSmGetServiceLogState( LW_SERVICE_HANDLE hHandle, LW_PCSTR pFacility, PLW_SM_LOGGER_TYPE pType, LW_PSTR* ppTarget, PLW_SM_LOG_LEVEL pLevel ) { DWORD dwError = 0; LWMsgCall* pCall = NULL; LWMsgParams in = LWMSG_PARAMS_INITIALIZER; LWMsgParams out = LWMSG_PARAMS_INITIALIZER; SM_GET_LOG_STATE_REQ req = {0}; PSM_GET_LOG_STATE_RES pRes = NULL; req.hHandle = (LWMsgHandle*) hHandle; req.pFacility = (PSTR) pFacility; in.tag = SM_IPC_GET_LOG_STATE_REQ; in.data = &req; dwError = LwSmIpcAcquireCall(&pCall); BAIL_ON_ERROR(dwError); dwError = MAP_LWMSG_STATUS(lwmsg_call_dispatch(pCall, &in, &out, NULL, NULL)); BAIL_ON_ERROR(dwError); switch (out.tag) { case SM_IPC_GET_LOG_STATE_RES: pRes = out.data; *pType = pRes->type; *ppTarget = pRes->pszTarget; *pLevel = pRes->Level; pRes->pszTarget = NULL; break; case SM_IPC_ERROR: dwError = *(PDWORD) out.data; BAIL_ON_ERROR(dwError); break; default: dwError = LW_ERROR_INTERNAL; BAIL_ON_ERROR(dwError); break; } cleanup: if (pCall) { lwmsg_call_destroy_params(pCall, &out); lwmsg_call_release(pCall); } return dwError; error: goto cleanup; }
DWORD LwSmGetGlobal( LW_IN LW_SM_GLOBAL_SETTING Setting, ... ) { DWORD dwError = 0; LWMsgCall* pCall = NULL; LWMsgParams in = LWMSG_PARAMS_INITIALIZER; LWMsgParams out = LWMSG_PARAMS_INITIALIZER; SM_GET_GLOBAL_REQ req = {0}; PSM_GLOBAL_VALUE pValue = NULL; va_list ap; req.Setting = Setting; in.tag = SM_IPC_GET_GLOBAL_REQ; in.data = &req; dwError = LwSmIpcAcquireCall(&pCall); BAIL_ON_ERROR(dwError); dwError = MAP_LWMSG_STATUS(lwmsg_call_dispatch(pCall, &in, &out, NULL, NULL)); BAIL_ON_ERROR(dwError); switch (out.tag) { case SM_IPC_GET_GLOBAL_RES: pValue = out.data; break; case SM_IPC_ERROR: dwError = *(PDWORD) out.data; BAIL_ON_ERROR(dwError); break; default: dwError = LW_ERROR_INTERNAL; BAIL_ON_ERROR(dwError); break; } va_start(ap, Setting); switch (Setting) { case LW_SM_GLOBAL_SETTING_WATCHDOG: if (pValue->Type != SM_GLOBAL_TYPE_BOOLEAN) { dwError = LW_ERROR_INTERNAL; } else { *(va_arg(ap, PBOOLEAN)) = pValue->Value.Boolean; } break; default: dwError = ERROR_INVALID_PARAMETER; break; } va_end(ap); BAIL_ON_ERROR(dwError); cleanup: if (pCall) { lwmsg_call_destroy_params(pCall, &out); lwmsg_call_release(pCall); } return dwError; error: goto cleanup; }
DWORD LwmEvtReadRecords( PLW_EVT_CLIENT_CONNECTION_CONTEXT pConn, IN DWORD MaxResults, IN PCWSTR pSqlFilter, OUT PDWORD pCount, OUT PLW_EVENTLOG_RECORD* ppRecords ) { DWORD dwError = 0; PEVT_IPC_GENERIC_ERROR pError = NULL; EVT_IPC_READ_RECORDS_REQ req = { 0 }; PEVT_IPC_RECORD_ARRAY pRes = NULL; LWMsgParams in = LWMSG_PARAMS_INITIALIZER; LWMsgParams out = LWMSG_PARAMS_INITIALIZER; LWMsgCall* pCall = NULL; dwError = LwmEvtAcquireCall(pConn, &pCall); BAIL_ON_EVT_ERROR(dwError); req.MaxResults = MaxResults; req.pFilter = pSqlFilter; in.tag = EVT_Q_READ_RECORDS; in.data = &req; dwError = MAP_LWMSG_ERROR(lwmsg_call_dispatch(pCall, &in, &out, NULL, NULL)); BAIL_ON_EVT_ERROR(dwError); switch (out.tag) { case EVT_R_READ_RECORDS: pRes = (PEVT_IPC_RECORD_ARRAY)out.data; *pCount = pRes->Count; *ppRecords = pRes->pRecords; pRes->Count = 0; pRes->pRecords = NULL; break; case EVT_R_GENERIC_ERROR: pError = (PEVT_IPC_GENERIC_ERROR) out.data; dwError = pError->Error; BAIL_ON_EVT_ERROR(dwError); break; default: dwError = LW_ERROR_INTERNAL; BAIL_ON_EVT_ERROR(dwError); } cleanup: if (pCall) { lwmsg_call_destroy_params(pCall, &out); lwmsg_call_release(pCall); } return dwError; error: *pCount = 0; *ppRecords = NULL; goto cleanup; }
MU_TEST(stress, parallel) { Data data; pthread_t threads[NUM_THREADS]; int i; LWMsgContext* context = NULL; LWMsgProtocol* protocol = NULL; LWMsgPeer* client = NULL; LWMsgPeer* server = NULL; CounterRequest request; CounterReply* reply; LWMsgCall* call; LWMsgParams in = LWMSG_PARAMS_INITIALIZER; LWMsgParams out = LWMSG_PARAMS_INITIALIZER; LWMsgTime timeout = {1, 0}; MU_TRY(lwmsg_context_new(NULL, &context)); lwmsg_context_set_log_function(context, lwmsg_test_log_function, NULL); MU_TRY(lwmsg_protocol_new(context, &protocol)); MU_TRY(lwmsg_protocol_add_protocol_spec(protocol, counterprotocol_spec)); MU_TRY(lwmsg_peer_new(context, protocol, &server)); MU_TRY(lwmsg_peer_add_dispatch_spec(server, counter_dispatch)); MU_TRY(lwmsg_peer_add_listen_endpoint(server, LWMSG_CONNECTION_MODE_LOCAL, TEST_ENDPOINT, 0600)); MU_TRY(lwmsg_peer_set_max_listen_clients(server, MAX_CLIENTS)); MU_TRY(lwmsg_peer_set_timeout(server, LWMSG_TIMEOUT_IDLE, &timeout)); MU_TRY(lwmsg_peer_start_listen(server)); MU_TRY(lwmsg_peer_new(context, protocol, &client)); MU_TRY(lwmsg_peer_add_connect_endpoint(client, LWMSG_CONNECTION_MODE_LOCAL, TEST_ENDPOINT)); request.counter = 0; MU_TRY(lwmsg_peer_acquire_call(client, &call)); in.tag = COUNTER_OPEN; in.data = &request; MU_TRY(lwmsg_call_dispatch(call, &in, &out, NULL, NULL)); MU_ASSERT_EQUAL(MU_TYPE_INTEGER, out.tag, COUNTER_OPEN_SUCCESS); lwmsg_call_release(call); data.client = client; data.handle = out.data; data.iters = NUM_ITERS; data.go = 0; pthread_mutex_init(&data.lock, NULL); pthread_cond_init(&data.event, NULL); pthread_mutex_lock(&data.lock); for (i = 0; i < NUM_THREADS; i++) { pthread_create(&threads[i], NULL, add_thread, &data); } data.go = 1; pthread_cond_broadcast(&data.event); pthread_mutex_unlock(&data.lock); for (i = 0; i < NUM_THREADS; i++) { pthread_join(threads[i], NULL); } MU_TRY(lwmsg_peer_acquire_call(client, &call)); in.tag = COUNTER_READ; in.data = data.handle; MU_TRY(lwmsg_call_dispatch(call, &in, &out, NULL, NULL)); MU_ASSERT_EQUAL(MU_TYPE_INTEGER, out.tag, COUNTER_READ_SUCCESS); reply = out.data; MU_ASSERT_EQUAL(MU_TYPE_INTEGER, reply->counter, NUM_THREADS * NUM_ITERS); lwmsg_call_destroy_params(call, &out); lwmsg_call_release(call); MU_TRY(lwmsg_peer_acquire_call(client, &call)); in.tag = COUNTER_CLOSE; in.data = data.handle; MU_TRY(lwmsg_call_dispatch(call, &in, &out, NULL, NULL)); MU_ASSERT_EQUAL(MU_TYPE_INTEGER, out.tag, COUNTER_CLOSE_SUCCESS); lwmsg_call_destroy_params(call, &out); lwmsg_call_release(call); MU_TRY(lwmsg_peer_disconnect(client)); lwmsg_peer_delete(client); MU_TRY(lwmsg_peer_stop_listen(server)); lwmsg_peer_delete(server); pthread_mutex_destroy(&data.lock); pthread_cond_destroy(&data.event); }