コード例 #1
0
PSTORAGE_DESCRIPTOR_HEADER
pStorageQueryProperty(
	HANDLE hDevice,
	STORAGE_PROPERTY_ID PropertyId,
	STORAGE_QUERY_TYPE  QueryType)
{
	STORAGE_PROPERTY_QUERY spquery;
	::ZeroMemory(&spquery, sizeof(spquery));
	spquery.PropertyId = PropertyId;
	spquery.QueryType = QueryType;

	DWORD bufferLength = sizeof(STORAGE_DESCRIPTOR_HEADER);
	XTL::AutoProcessHeapPtr<STORAGE_DESCRIPTOR_HEADER> buffer =
		static_cast<STORAGE_DESCRIPTOR_HEADER*>(
			::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, bufferLength));
	if (buffer.IsInvalid())
	{
		return NULL;
	}

	DWORD returnedLength;
	BOOL fSuccess = ::DeviceIoControl(
		hDevice, IOCTL_STORAGE_QUERY_PROPERTY, 
		&spquery, sizeof(spquery),
		buffer, bufferLength,
		&returnedLength, NULL);
	if (!fSuccess)
	{
		XTLTRACE_ERR("IOCTL_STORAGE_QUERY_PROPERTY(HEADER) failed.\n");
		return NULL;
	}

	// We only retrived the header, now we reallocate the buffer
	// required for the actual query
	bufferLength = buffer->Size; 
	XTL::AutoProcessHeapPtr<STORAGE_DESCRIPTOR_HEADER> newBuffer =
		static_cast<STORAGE_DESCRIPTOR_HEADER*>(
			::HeapReAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, buffer, bufferLength));
	if (newBuffer.IsInvalid())
	{
		return NULL;
	}
	// set the buffer with the new buffer
	buffer.Detach();
	buffer = newBuffer.Detach();
	
	// now we can query the actual property with the proper size
	fSuccess = ::DeviceIoControl(
		hDevice, IOCTL_STORAGE_QUERY_PROPERTY, 
		&spquery, sizeof(spquery),
		buffer, bufferLength,
		&returnedLength, NULL);
	if (!fSuccess)
	{
		XTLTRACE_ERR("IOCTL_STORAGE_QUERY_PROPERTY(DATA) failed.\n");
		return NULL;
	}

	return buffer.Detach();
}
コード例 #2
0
DWORD 
CNdasCommandServer::
ThreadStart(LPVOID lpParam)
{
	HANDLE hStopEvent = static_cast<HANDLE>(lpParam);

	CmdWorkItemVector workItems;
	workItems.reserve(MaxPipeInstances);

	size_t size = workItems.size();
	XTLASSERT(0 == size);
	std::generate_n(
		std::back_inserter(workItems), 
		MaxPipeInstances, 
		pWorkItemPtrGenerator);
	size = workItems.size();
	XTLASSERT(MaxPipeInstances == size);

	DWORD nWorkItems = 0;

	for (DWORD i = 0; i < MaxPipeInstances; ++i)
	{
		CmdWorkItemPtr p = workItems[i];
		BOOL fSuccess = p->QueueUserWorkItemEx(
			this, 
			&CNdasCommandServer::CommandProcessStart, 
			hStopEvent, 
			WT_EXECUTELONGFUNCTION);
		if (fSuccess)
		{
			++nWorkItems;
		}
		else
		{
			XTLTRACE_ERR("Starting work item (%d/%d) failed.\n", i + 1, MaxPipeInstances);
		}
	}

	// Release semaphore to start workers (semaphore increment)
	LONG prev;
	XTLVERIFY( ::ReleaseSemaphore(m_hProcSemaphore, nWorkItems, &prev) );
	XTLASSERT( 0 == prev );

	// Wait for stop event
	XTLVERIFY(WAIT_OBJECT_0 == ::WaitForSingleObject(hStopEvent, INFINITE));

	// Stopped and waits for user work items
	DWORD finished = 0;
	while (finished < nWorkItems)
	{
		::Sleep(0);
		DWORD waitResult = ::WaitForSingleObject(m_hProcSemaphore, 0);
		if (waitResult == WAIT_OBJECT_0)
		{
			XTLTRACE("Command Process work item finished (%d/%d).\n", finished + 1, nWorkItems);
			++finished;
		}
		XTLVERIFY(WAIT_OBJECT_0 == waitResult || WAIT_TIMEOUT == waitResult);
	}

	// Now Finally this thread can stop
	return 0;
}
コード例 #3
0
DWORD 
CNdasCommandServer::ServiceCommand(HANDLE hStopEvent)
{

	// Named Pipe Connection Event
	XTL::AutoObjectHandle hConnectEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);

	if (hConnectEvent.IsInvalid()) 
	{
		// Log Error Here
		XTLTRACE_ERR("Creating ndascmd connection event failed.\n");
		return 1;
	}

	// Create a named pipe instance
	XTL::AutoFileHandle hPipe = ::CreateNamedPipe(
		PipeName,
		PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, // | FILE_FLAG_FIRST_PIPE_INSTANCE,
		PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
		MaxPipeInstances, 
		0,
		0,
		PipeTimeout,
		NULL);

	if (hPipe.IsInvalid()) 
	{
		// Log Error Here
		XTLTRACE_ERR("Creating pipe server failed.\n");
		return 2;
	}

	HANDLE waitHandles[] = { hStopEvent, hConnectEvent };
	const DWORD nWaitHandles = RTL_NUMBER_OF(waitHandles);

	while (TRUE) 
	{
		// Initialize overlapped structure
		OVERLAPPED overlapped = {0};
		overlapped.hEvent = hConnectEvent;
		XTLVERIFY( ::ResetEvent(hConnectEvent) );

		CNamedPipeTransport namePipeTransport(hPipe);
		CNamedPipeTransport* pTransport = &namePipeTransport;

		BOOL fSuccess = pTransport->Accept(&overlapped);
		if (!fSuccess) 
		{ 
			XTLTRACE_ERR("Transport Accept (Named Pipe) failed.\n");
			break;
		}

		DWORD waitResult = ::WaitForMultipleObjects(
			nWaitHandles, waitHandles, FALSE, INFINITE);

		switch (waitResult) 
		{
		case WAIT_OBJECT_0: // Terminate Thread Event
			return 0;
		case WAIT_OBJECT_0 + 1: // Connect Event
			//
			// Process the request
			// (Safely ignore error)
			//
			{
				CNdasCommandProcessor processor(m_service, pTransport);
				if (!processor.Process())
				{
					XTLTRACE_ERR("CommandProcess failed.\n");
				}
				// After processing the request, reset the pipe instance
				XTLVERIFY( ::FlushFileBuffers(hPipe) );
				XTLVERIFY( ::DisconnectNamedPipe(hPipe) );
			}			
			break;
		default:
			XTLTRACE_ERR("Wait failed.\n");
			XTLASSERT(FALSE);
		}
	}

	return 0;
}