
Dreams come true
생각하는대로 살지 않으면 사는대로 생각한다.
2010년 5월 17일 월요일
2009년 11월 24일 화요일
[2010 시간관리페스티벌] High Performer's Secret


관련 페이지 : http://www.franklinplanner.co.kr/tmf/2010/default.aspx
프랭클린플래너에서 "시간관리 페스티벌"을 개최합니다!
제가 생각하는 Hight Performer는 시간을 효율적으로 사용할 줄 알고, 현재를 즐길 줄 아는..
그런것이 아닐까 생각되는데요^^
아직 시간관리를 효율적으로 하지 못하고, 대화에 있어서도 부족한 점이 많은데 "시간관리 페스티벌"을 통해 부족한 점을 배우고 Hight Performer로서 나아가는 걸음이 되었으면 좋겠습니다.
여러분도 함께 참여해보시는 것은 어떠세요?!
2009년 11월 16일 월요일
2009년 11월 8일 일요일
TransmitFile()에 대해서..
BOOL TransmitFile (
SOCKET hSocket,
Handle hFile,
DWORD를 nNumberOfBytesToWrite,
DWORD를 nNumberOfBytesPerSend,
LPOVERLAPPED lpOverlapped,
LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers,
DWORD를 dwFlags
);
첫번째 인자 : 파일을 전송할 소켓의 핸들
두번째 인자 : 전송할 파일의 핸들 (반드시 FILE_FLAG_SEQUENTIAL_SCAN 속성이 주어져야 한다. 이 속성은 파일을 처음부터 끝까지 순차적으로만 접근한다는 의미이다.)
세번째 인자 : 전송할 파일의 크기 (0으로 하면 파일 전체를 전송)
네번째 인자 : 파일을 전송할 때 내부적으로 ::send()함수를 사용하며 이때 버퍼의 크기를 얼마로 할것인지 명시하는 것.
다섯번째 인자 : OVERLAPPED 구조체에 대한 포인터(네트워크 입/출력을 비동기적으로 처리할 수 있도록 하였다면 이부분도 지원해 준다. 동기적 처리는 NULL)
여섯번째 인자 : TRANSMIT_FILE_BUFFERS 구조체에 대한 포인터(NULL 이면 파일 내용만 전송)
마지막 인자 : 기타 옵션
[ TF_DISCONNECT : 전송 작업이 완료되면 트랜스포트 레벨 접속을 끊는다.
TF_REUSE_SOCKET : 전송 작업이 완료된 이후에 소켓을 재사용 할 수 있도록 한다.
이 소켓은 AcceptEx 함수에 의해 재활용 될 수 있다. 이 플래그
는 TF_DISCONNECT와 함께 사용해야함.
TF_USE_DEFAULT_WORKER : 시스템 디폴트 스레드를 이용해서 파일을 전송한다.
이 플래그는 큰 파일을 전송할 때 유용하다.
TF_USE_SYSTEM_THREAD : 시스템 스레드를 이용해서 파일을 전송한다.
TF_USE_KERNEL_APC : 전송 작업을 처리하는데 커널 APC를 사용한다. 커널 APC는
응용프로그램이 대기 상태일 때 작동된다.(경고성 대기 상태
일 필요는 없다).
TF_WRITE_BEHIND : TrnasmitFile 호출이 데이터가 전송 완료되기 전에 리턴된다. TF_DISCONNECT나 TF_REUSE_SOCKET 플래그와 함께 사용할 수 없다.]
Stdafx.h 파일을 열어서 ::TransmitFile() 함수에 대한 정보가 담긴 헤더와 라이브러리 설정 코드를 추가한 다음 결과를 확인한다!
#include <Mswsock.h>
#pragma comment(lib, "Mswsock.lib")
어떻게 사용했냐..간단히 함수 부분만 넣어보겠다.
ret = TransmitFile(ClientSock, hFileSource, (DWORD)0, 15000, NULL, NULL,
TF_DISCONNECT);
if (ret == SOCKET_ERROR)
{
strTmp.Format("TransmitFile error code : %d", WSAGetLastError());
AfxMessageBox(strTmp);
}
else {
strTmp = "파일 전송이 완료되었습니다.";
InsertChatStr(strTmp,3);
}
Winsock 에러 코드!
WSAEACCES 10013
WSAEFAULT 10014
WSAEINPROGRESS 10036
WSAENETDOWN 10050
WSAENETUNREACH 10051
WSAENETRESET 10052
WSAECONNABORTED 10053
WSAECONNRESET 10054
WSAENOBUFS 10055
WSAEISCONN 10056
WSAENOTCONN 10057
WSASHUTDOWN 10058
WSAETOOMANYREFS 10059
WSAETIMEDOUT 10060
WSAECONNREFUSED 10061
WSAELOOP 10062
Answer/Solution: A pathname lookup involved more than eight symbolic links. (Too many links were encountered in translating a pathname.)
WSAENAMETOOLONG 10063
-
A socket operation failed because the destination host was down.
-
A socket operation encountered a dead host.
-
Networking activity on the local host has not been initiated.
WSAHOSTUNREACH 10065
WSASYSNOTREADY 10091
WSAVERNOTSUPPORTED 10092
WSANOTINITIALISED 10093
WSAHOST_NOT_FOUND 11001
WSATRY_AGAIN 11002
WSANO_RECOVERY 11003
WSANO_DATA 11004
[소스분석] WDF sample source - Osrubsfx2 : device.c
/*++
Copyright (c) Microsoft Corporation. All rights reserved.
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
PURPOSE.
Module Name:
Device.c
Abstract:
USB device driver for OSR USB-FX2 Learning Kit
Environment:
Kernel mode only
--*/
#include <osrusbfx2.h>
#if defined(EVENT_TRACING)
#include "device.tmh"
#endif
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, OsrFxEvtDeviceAdd)
#pragma alloc_text(PAGE, OsrFxEvtDevicePrepareHardware)
#pragma alloc_text(PAGE, OsrFxEvtDeviceD0Exit)
#pragma alloc_text(PAGE, SelectInterfaces)
#pragma alloc_text(PAGE, OsrFxSetPowerPolicy)
#pragma alloc_text(PAGE, OsrFxReadFdoRegistryKeyValue)
#endif
NTSTATUS
OsrFxEvtDeviceAdd(
__in WDFDRIVER Driver,
__in PWDFDEVICE_INIT DeviceInit
)
/*++
Routine Description:
EvtDeviceAdd is called by the framework in response to AddDevice
call from the PnP manager. We create and initialize a device object to
represent a new instance of the device. All the software resources
should be allocated in this callback.
Arguments:
Driver - Handle to a framework driver object created in DriverEntry
DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure.
Return Value:
NTSTATUS
--*/
{
WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;
WDF_OBJECT_ATTRIBUTES attributes;
NTSTATUS status;
WDFDEVICE device;
WDF_DEVICE_PNP_CAPABILITIES pnpCaps;
WDF_IO_QUEUE_CONFIG ioQueueConfig;
PDEVICE_CONTEXT pDevContext;
WDFQUEUE queue;
UNREFERENCED_PARAMETER(Driver);
PAGED_CODE();
TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,"--> OsrFxEvtDeviceAdd routine\n");
//
// Initialize the pnpPowerCallbacks structure. Callback events for PNP
// and Power are specified here. If you don't supply any callbacks,
// the Framework will take appropriate default actions based on whether
// DeviceInit is initialized to be an FDO, a PDO or a filter device
// object.
//
WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);
//
// For usb devices, PrepareHardware callback is the to place select the
// interface and configure the device.
//
pnpPowerCallbacks.EvtDevicePrepareHardware = OsrFxEvtDevicePrepareHardware;
//
// These two callbacks start and stop the wdfusb pipe continuous reader
// as we go in and out of the D0-working state.
//
pnpPowerCallbacks.EvtDeviceD0Entry = OsrFxEvtDeviceD0Entry;
pnpPowerCallbacks.EvtDeviceD0Exit = OsrFxEvtDeviceD0Exit;
WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);
WdfDeviceInitSetIoType(DeviceInit, WdfDeviceIoBuffered);
//
// Now specify the size of device extension where we track per device
// context.DeviceInit is completely initialized. So call the framework
// to create the device and attach it to the lower stack.
//
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, DEVICE_CONTEXT);
status = WdfDeviceCreate(&DeviceInit, &attributes, &device);
if (!NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
"WdfDeviceCreate failed with Status code %!STATUS!\n", status);
return status;
}
//
// Get the DeviceObject context by using accessor function specified in
// the WDF_DECLARE_CONTEXT_TYPE_WITH_NAME macro for DEVICE_CONTEXT.
//
pDevContext = GetDeviceContext(device);
//
// Tell the framework to set the SurpriseRemovalOK in the DeviceCaps so
// that you don't get the popup in usermode (on Win2K) when you surprise
// remove the device.
//
WDF_DEVICE_PNP_CAPABILITIES_INIT(&pnpCaps);
pnpCaps.SurpriseRemovalOK = WdfTrue;
WdfDeviceSetPnpCapabilities(device, &pnpCaps);
//
// Create a parallel default queue and register an event callback to
// receive ioctl requests. We will create separate queues for
// handling read and write requests. All other requests will be
// completed with error status automatically by the framework.
//
WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&ioQueueConfig,
WdfIoQueueDispatchParallel);
ioQueueConfig.EvtIoDeviceControl = OsrFxEvtIoDeviceControl;
status = WdfIoQueueCreate(device,
&ioQueueConfig,
WDF_NO_OBJECT_ATTRIBUTES,
&queue);// pointer to default queue
if (!NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
"WdfIoQueueCreate failed %!STATUS!\n", status);
return status;
}
//
// We will create a separate sequential queue and configure it
// to receive read requests. We also need to register a EvtIoStop
// handler so that we can acknowledge requests that are pending
// at the target driver.
//
WDF_IO_QUEUE_CONFIG_INIT(&ioQueueConfig, WdfIoQueueDispatchSequential);
ioQueueConfig.EvtIoRead = OsrFxEvtIoRead;
ioQueueConfig.EvtIoStop = OsrFxEvtIoStop;
status = WdfIoQueueCreate(
device,
&ioQueueConfig,
WDF_NO_OBJECT_ATTRIBUTES,
&queue // queue handle
);
if (!NT_SUCCESS (status)) {
TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
"WdfIoQueueCreate failed 0x%x\n", status);
return status;
}
status = WdfDeviceConfigureRequestDispatching(
device,
queue,
WdfRequestTypeRead);
if(!NT_SUCCESS (status)){
ASSERT(NT_SUCCESS(status));
TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
"WdfDeviceConfigureRequestDispatching failed 0x%x\n", status);
return status;
}
//
// We will create another sequential queue and configure it
// to receive write requests.
//
WDF_IO_QUEUE_CONFIG_INIT(&ioQueueConfig, WdfIoQueueDispatchSequential);
ioQueueConfig.EvtIoWrite = OsrFxEvtIoWrite;
ioQueueConfig.EvtIoStop = OsrFxEvtIoStop;
status = WdfIoQueueCreate(
device,
&ioQueueConfig,
WDF_NO_OBJECT_ATTRIBUTES,
&queue // queue handle
);
if (!NT_SUCCESS (status)) {
TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
"WdfIoQueueCreate failed 0x%x\n", status);
return status;
}
status = WdfDeviceConfigureRequestDispatching(
device,
queue,
WdfRequestTypeWrite);
if(!NT_SUCCESS (status)){
ASSERT(NT_SUCCESS(status));
TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
"WdfDeviceConfigureRequestDispatching failed 0x%x\n", status);
return status;
}
//
// Register a manual I/O queue for handling Interrupt Message Read Requests.
// This queue will be used for storing Requests that need to wait for an
// interrupt to occur before they can be completed.
//
WDF_IO_QUEUE_CONFIG_INIT(&ioQueueConfig, WdfIoQueueDispatchManual);
//
// This queue is used for requests that dont directly access the device. The
// requests in this queue are serviced only when the device is in a fully
// powered state and sends an interrupt. So we can use a non-power managed
// queue to park the requests since we dont care whether the device is idle
// or fully powered up.
//
ioQueueConfig.PowerManaged = WdfFalse;
status = WdfIoQueueCreate(device,
&ioQueueConfig,
WDF_NO_OBJECT_ATTRIBUTES,
&pDevContext->InterruptMsgQueue
);
if (!NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
"WdfIoQueueCreate failed 0x%x\n", status);
return status;
}
//
// Register a device interface so that app can find our device and talk to it.
//
status = WdfDeviceCreateDeviceInterface(device,
(LPGUID) &GUID_DEVINTERFACE_OSRUSBFX2,
NULL);// Reference String
if (!NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
"WdfDeviceCreateDeviceInterface failed %!STATUS!\n", status);
return status;
}
TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "<-- OsrFxEvtDeviceAdd\n");
return status;
}
NTSTATUS
OsrFxEvtDevicePrepareHardware(
__in WDFDEVICE Device,
__in WDFCMRESLIST ResourceList,
__in WDFCMRESLIST ResourceListTranslated
)
/*++
Routine Description:
In this callback, the driver does whatever is necessary to make the
hardware ready to use. In the case of a USB device, this involves
reading and selecting descriptors.
Arguments:
Device - handle to a device
Return Value:
NT status value
--*/
{
NTSTATUS status;
PDEVICE_CONTEXT pDeviceContext;
WDF_USB_DEVICE_INFORMATION deviceInfo;
ULONG waitWakeEnable;
UNREFERENCED_PARAMETER(ResourceList);
UNREFERENCED_PARAMETER(ResourceListTranslated);
PAGED_CODE();
TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> EvtDevicePrepareHardware\n");
pDeviceContext = GetDeviceContext(Device);
//
// Create a USB device handle so that we can communicate with the
// underlying USB stack. The WDFUSBDEVICE handle is used to query,
// configure, and manage all aspects of the USB device.
// These aspects include device properties, bus properties,
// and I/O creation and synchronization. We only create device the first
// the PrepareHardware is called. If the device is restarted by pnp manager
// for resource rebalance, we will use the same device handle but then select
// the interfaces again because the USB stack could reconfigure the device on
// restart.
//
if (pDeviceContext->UsbDevice == NULL) {
status = WdfUsbTargetDeviceCreate(Device,
WDF_NO_OBJECT_ATTRIBUTES,
&pDeviceContext->UsbDevice);
if (!NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
"WdfUsbTargetDeviceCreate failed with Status code %!STATUS!\n", status);
return status;
}
}
status = SelectInterfaces(Device);
if (!NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
"SelectInterfaces failed 0x%x\n", status);
return status;
}
//
// Retrieve USBD version information, port driver capabilites and device
// capabilites such as speed, power, etc.
//
WDF_USB_DEVICE_INFORMATION_INIT(&deviceInfo);
status = WdfUsbTargetDeviceRetrieveInformation(
pDeviceContext->UsbDevice,
&deviceInfo);
if (NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "IsDeviceHighSpeed: %s\n",
(deviceInfo.Traits & WDF_USB_DEVICE_TRAIT_AT_HIGH_SPEED) ? "TRUE" : "FALSE");
}
TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,
"IsDeviceSelfPowered: %s\n",
(deviceInfo.Traits & WDF_USB_DEVICE_TRAIT_SELF_POWERED) ? "TRUE" : "FALSE");
waitWakeEnable = deviceInfo.Traits &
WDF_USB_DEVICE_TRAIT_REMOTE_WAKE_CAPABLE;
TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,
"IsDeviceRemoteWakeable: %s\n",
waitWakeEnable ? "TRUE" : "FALSE");
//
// Enable wait-wake and idle timeout if the device supports it
//
if(waitWakeEnable){
status = OsrFxSetPowerPolicy(Device);
if (!NT_SUCCESS (status)) {
TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
"OsrFxSetPowerPolicy failed %!STATUS!\n", status);
return status;
}
}
status = OsrFxConfigContReaderForInterruptEndPoint(pDeviceContext);
TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "<-- EvtDevicePrepareHardware\n");
return status;
}
NTSTATUS
OsrFxEvtDeviceD0Entry(
__in WDFDEVICE Device,
__in WDF_POWER_DEVICE_STATE PreviousState
)
/*++
Routine Description:
EvtDeviceD0Entry event callback must perform any operations that are
necessary before the specified device is used. It will be called every
time the hardware needs to be (re-)initialized.
This function is not marked pageable because this function is in the
device power up path. When a function is marked pagable and the code
section is paged out, it will generate a page fault which could impact
the fast resume behavior because the client driver will have to wait
until the system drivers can service this page fault.
This function runs at PASSIVE_LEVEL, even though it is not paged. A
driver can optionally make this function pageable if DO_POWER_PAGABLE
is set. Even if DO_POWER_PAGABLE isn't set, this function still runs
at PASSIVE_LEVEL. In this case, though, the function absolutely must
not do anything that will cause a page fault.
Arguments:
Device - Handle to a framework device object.
PreviousState - Device power state which the device was in most recently.
If the device is being newly started, this will be
PowerDeviceUnspecified.
Return Value:
NTSTATUS
--*/
{
PDEVICE_CONTEXT pDeviceContext;
NTSTATUS status;
pDeviceContext = GetDeviceContext(Device);
TraceEvents(TRACE_LEVEL_INFORMATION, DBG_POWER,
"-->OsrFxEvtEvtDeviceD0Entry - coming from %s\n",
DbgDevicePowerString(PreviousState));
status = WdfIoTargetStart(WdfUsbTargetPipeGetIoTarget(pDeviceContext->InterruptPipe));
TraceEvents(TRACE_LEVEL_INFORMATION, DBG_POWER, "<--OsrFxEvtEvtDeviceD0Entry\n");
return status;
}
NTSTATUS
OsrFxEvtDeviceD0Exit(
__in WDFDEVICE Device,
__in WDF_POWER_DEVICE_STATE TargetState
)
/*++
Routine Description:
This routine undoes anything done in EvtDeviceD0Entry. It is called
whenever the device leaves the D0 state, which happens when the device is
stopped, when it is removed, and when it is powered off.
The device is still in D0 when this callback is invoked, which means that
the driver can still touch hardware in this routine.
EvtDeviceD0Exit event callback must perform any operations that are
necessary before the specified device is moved out of the D0 state. If the
driver needs to save hardware state before the device is powered down, then
that should be done here.
This function runs at PASSIVE_LEVEL, though it is generally not paged. A
driver can optionally make this function pageable if DO_POWER_PAGABLE is set.
Even if DO_POWER_PAGABLE isn't set, this function still runs at
PASSIVE_LEVEL. In this case, though, the function absolutely must not do
anything that will cause a page fault.
Arguments:
Device - Handle to a framework device object.
TargetState - Device power state which the device will be put in once this
callback is complete.
Return Value:
Success implies that the device can be used. Failure will result in the
device stack being torn down.
--*/
{
PDEVICE_CONTEXT pDeviceContext;
PAGED_CODE();
TraceEvents(TRACE_LEVEL_INFORMATION, DBG_POWER,
"-->OsrFxEvtDeviceD0Exit - moving to %s\n",
DbgDevicePowerString(TargetState));
pDeviceContext = GetDeviceContext(Device);
WdfIoTargetStop(WdfUsbTargetPipeGetIoTarget(pDeviceContext->InterruptPipe),
WdfIoTargetCancelSentIo);
TraceEvents(TRACE_LEVEL_INFORMATION, DBG_POWER, "<--OsrFxEvtDeviceD0Exit\n");
return STATUS_SUCCESS;
}
__drv_requiresIRQL(PASSIVE_LEVEL)
NTSTATUS
OsrFxSetPowerPolicy(
__in WDFDEVICE Device
)
{
WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS idleSettings;
WDF_DEVICE_POWER_POLICY_WAKE_SETTINGS wakeSettings;
NTSTATUS status = STATUS_SUCCESS;
PAGED_CODE();
//
// Init the idle policy structure.
//
WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS_INIT(&idleSettings, IdleUsbSelectiveSuspend);
idleSettings.IdleTimeout = 10000; // 10-sec
status = WdfDeviceAssignS0IdleSettings(Device, &idleSettings);
if ( !NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
"WdfDeviceSetPowerPolicyS0IdlePolicy failed %x\n", status);
return status;
}
//
// Init wait-wake policy structure.
//
WDF_DEVICE_POWER_POLICY_WAKE_SETTINGS_INIT(&wakeSettings);
status = WdfDeviceAssignSxWakeSettings(Device, &wakeSettings);
if (!NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
"WdfDeviceAssignSxWakeSettings failed %x\n", status);
return status;
}
return status;
}
__drv_requiresIRQL(PASSIVE_LEVEL)
NTSTATUS
SelectInterfaces(
__in WDFDEVICE Device
)
/*++
Routine Description:
This helper routine selects the configuration, interface and
creates a context for every pipe (end point) in that interface.
Arguments:
Device - Handle to a framework device
Return Value:
NT status value
--*/
{
WDF_USB_DEVICE_SELECT_CONFIG_PARAMS configParams;
NTSTATUS status;
PDEVICE_CONTEXT pDeviceContext;
WDFUSBPIPE pipe;
WDF_USB_PIPE_INFORMATION pipeInfo;
UCHAR index;
UCHAR numberConfiguredPipes;
PAGED_CODE();
pDeviceContext = GetDeviceContext(Device);
WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE( &configParams);
status = WdfUsbTargetDeviceSelectConfig(pDeviceContext->UsbDevice,
WDF_NO_OBJECT_ATTRIBUTES,
&configParams);
if(!NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
"WdfUsbTargetDeviceSelectConfig failed %!STATUS!\n",
status);
return status;
}
pDeviceContext->UsbInterface =
configParams.Types.SingleInterface.ConfiguredUsbInterface;
numberConfiguredPipes = configParams.Types.SingleInterface.NumberConfiguredPipes;
//
// Get pipe handles
//
for(index=0; index < numberConfiguredPipes; index++) {
WDF_USB_PIPE_INFORMATION_INIT(&pipeInfo);
pipe = WdfUsbInterfaceGetConfiguredPipe(
pDeviceContext->UsbInterface,
index, //PipeIndex,
&pipeInfo
);
//
// Tell the framework that it's okay to read less than
// MaximumPacketSize
//
WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(pipe);
if(WdfUsbPipeTypeInterrupt == pipeInfo.PipeType) {
TraceEvents(TRACE_LEVEL_INFORMATION, DBG_IOCTL,
"Interrupt Pipe is 0x%p\n", pipe);
pDeviceContext->InterruptPipe = pipe;
}
if(WdfUsbPipeTypeBulk == pipeInfo.PipeType &&
WdfUsbTargetPipeIsInEndpoint(pipe)) {
TraceEvents(TRACE_LEVEL_INFORMATION, DBG_IOCTL,
"BulkInput Pipe is 0x%p\n", pipe);
pDeviceContext->BulkReadPipe = pipe;
}
if(WdfUsbPipeTypeBulk == pipeInfo.PipeType &&
WdfUsbTargetPipeIsOutEndpoint(pipe)) {
TraceEvents(TRACE_LEVEL_INFORMATION, DBG_IOCTL,
"BulkOutput Pipe is 0x%p\n", pipe);
pDeviceContext->BulkWritePipe = pipe;
}
}
//
// If we didn't find all the 3 pipes, fail the start.
//
if(!(pDeviceContext->BulkWritePipe
&& pDeviceContext->BulkReadPipe && pDeviceContext->InterruptPipe)) {
status = STATUS_INVALID_DEVICE_STATE;
TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
"Device is not configured properly %!STATUS!\n",
status);
return status;
}
return status;
}
__drv_requiresIRQL(PASSIVE_LEVEL)
PCHAR
DbgDevicePowerString(
__in WDF_POWER_DEVICE_STATE Type
)
/*++
Updated Routine Description:
DbgDevicePowerString does not change in this stage of the function driver.
--*/
{
switch (Type)
{
case WdfPowerDeviceInvalid:
return "WdfPowerDeviceInvalid";
case WdfPowerDeviceD0:
return "WdfPowerDeviceD0";
case PowerDeviceD1:
return "WdfPowerDeviceD1";
case WdfPowerDeviceD2:
return "WdfPowerDeviceD2";
case WdfPowerDeviceD3:
return "WdfPowerDeviceD3";
case WdfPowerDeviceD3Final:
return "WdfPowerDeviceD3Final";
case WdfPowerDevicePrepareForHibernation:
return "WdfPowerDevicePrepareForHibernation";
case WdfPowerDeviceMaximum:
return "PowerDeviceMaximum";
default:
return "UnKnown Device Power State";
}
}
[소스분석] WDF sample source - Osrubsfx2 : driver.c
// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // //
// driver.c
// 함수 : DriverEntry(),
OsrFxEvtDriverContextCleanup(),
TraceEvents()
// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // //
#include <osrusbfx2.h>
#if defined(EVENT_TRACING)
//
// The trace message header (.tmh) file must be included in a source file
// before any WPP macro calls and after defining a WPP_CONTROL_GUIDS
// macro (defined in toaster.h). During the compilation, WPP scans the source
// files for DoTraceMessage() calls and builds a .tmh file which stores a unique
// data GUID for each message, the text resource string for each message,
// and the data types of the variables passed in for each message. This file
// is automatically generated and used during post-processing.
//
#include "driver.tmh"
#else
ULONG DebugLevel = TRACE_LEVEL_INFORMATION;
ULONG DebugFlag = 0xff;
#endif
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, DriverEntry)
#pragma alloc_text(PAGE, OsrFxEvtDriverContextCleanup)
#endif
// DriverEntry는 드라이버를 초기화하고, 드라이버가 로드된 후에 시스템으로부터 불려지는 첫번째 루틴이다.
__drv_requiresIRQL(PASSIVE_LEVEL)
NTSTATUS
DriverEntry(
__in PDRIVER_OBJECT DriverObject,
__in PUNICODE_STRING RegistryPath
)
/*++
Routine Description:
Parameters Description:
DriverObject - represents the instance of the function driver that is loaded
into memory. DriverEntry must initialize members of DriverObject before it
returns to the caller. DriverObject is allocated by the system before the
driver is loaded, and it is released by the system after the system unloads
the function driver from memory.
RegistryPath - represents the driver specific path in the Registry.
The function driver can use the path to store driver related data between
reboots. The path does not store hardware instance specific data.
Return Value:
STATUS_SUCCESS if successful,
STATUS_UNSUCCESSFUL otherwise.
--*/
{
WDF_DRIVER_CONFIG config;
NTSTATUS status;
WDF_OBJECT_ATTRIBUTES attributes; // object 속성
//
// Initialize WPP Tracing
//
WPP_INIT_TRACING( DriverObject, RegistryPath );
TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT,
"OSRUSBFX2 Driver Sample - Driver Framework Edition.\n");
TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT,
"Built %s %s\n", __DATE__, __TIME__);
//
// Initiialize driver config to control the attributes that
// are global to the driver. Note that framework by default
// provides a driver unload routine. If you create any resources
// in the DriverEntry and want to be cleaned in driver unload,
// you can override that by manually setting the EvtDriverUnload in the
// config structure. In general xxx_CONFIG_INIT macros are provided to
// initialize most commonly used members.
//
WDF_DRIVER_CONFIG_INIT( // WDF_DRIVER_CONFIG 구조체 초기화
&config,
OsrFxEvtDeviceAdd // device.c 함수
);
//
// Register a cleanup callback so that we can call WPP_CLEANUP when
// the framework driver object is deleted during driver unload.
//
WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
attributes.EvtCleanupCallback = OsrFxEvtDriverContextCleanup;
//
// Create a framework driver object to represent our driver.
//
status = WdfDriverCreate( // Framework Driver Object 생성
DriverObject,
RegistryPath,
&attributes, // Driver Object Attributes 이 둘은 생성하고자 하는 object 작동방식을
&config, // Driver Config Info 설정하는 파라미터이다.
WDF_NO_HANDLE // hDriver
);
if (!NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_ERROR, DBG_INIT,
"WdfDriverCreate failed with status 0x%x\n", status);
//
// Cleanup tracing here because DriverContextCleanup will not be called
// as we have failed to create WDFDRIVER object itself.
// Please note that if your return failure from DriverEntry after the
// WDFDRIVER object is created successfully, you don't have to
// call WPP cleanup because in those cases DriverContextCleanup
// will be executed when the framework deletes the DriverObject.
//
WPP_CLEANUP(DriverObject);
}
return status;
}
VOID
OsrFxEvtDriverContextCleanup(
__in WDFDRIVER Driver
)
/*++
Routine Description:
DriverEntry 안에 할당된 리소스를 해제한다.
Arguments:
Driver - handle to a WDF Driver object.
Return Value:
VOID.
--*/
{
PAGED_CODE (); // 특정 함수가 IRQL DISPATCH_LEBEL 또는 그 이상의 IRQL 레벨에서 동작하지 않으면
// Assert를 발생해주는 매크로
UNREFERENCED_PARAMETER(Driver); // Driver 파라미터를 이 함수에서 참조하지 않는다.
TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT,
"--> OsrFxEvtDriverContextCleanup\n");
WPP_CLEANUP( WdfDriverWdmGetDriverObject( Driver ));
}
#if !defined(EVENT_TRACING)
VOID
TraceEvents (
__in ULONG DebugPrintLevel,
__in ULONG DebugPrintFlag,
__drv_formatString(printf)
__in PCSTR DebugMessage,
...
)
/*++
Routine Description:
Debug print for the sample driver.
Arguments:
TraceEventsLevel - print level between 0 and 3, with 3 the most verbose
Return Value:
None.
--*/
{
#if DBG
#define TEMP_BUFFER_SIZE 1024
va_list list;
CHAR debugMessageBuffer[TEMP_BUFFER_SIZE];
NTSTATUS status;
va_start(list, DebugMessage);
if (DebugMessage) {
//
// Using new safe string functions instead of _vsnprintf.
// This function takes care of NULL terminating if the message
// is longer than the buffer.
//
status = RtlStringCbVPrintfA( debugMessageBuffer,
sizeof(debugMessageBuffer),
DebugMessage,
list );
if(!NT_SUCCESS(status)) {
DbgPrint (_DRIVER_NAME_": RtlStringCbVPrintfA failed 0x%x\n", status);
return;
}
if (DebugPrintLevel <= TRACE_LEVEL_ERROR ||
(DebugPrintLevel <= DebugLevel &&
((DebugPrintFlag & DebugFlag) == DebugPrintFlag))) {
DbgPrint("%s %s", _DRIVER_NAME_, debugMessageBuffer);
}
}
va_end(list);
return;
#else
UNREFERENCED_PARAMETER(TraceEventsLevel);
UNREFERENCED_PARAMETER(TraceEventsFlag);
UNREFERENCED_PARAMETER(DebugMessage);
#endif
}
#endif