zd001
驱动牛犊
驱动牛犊
  • 注册日期2001-10-12
  • 最后登录2004-09-30
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:2530回复:12

用DS开发驱动成功的朋友请指点

楼主#
更多 发布于:2002-05-26 14:33
我的USB设备是简单的读卡设备,读卡设备已基本没有问题,但用DS做的驱动安装后提示设备不能启动,用工具看发现描述表信息只有第一部分(后面的PIPE信息没有,但没有安装驱动时描述表信息齐全),我对驱动知道不多,请高人指点,该如何改?用DS生成的程序如下:
#pragma warning(disable:4065) // Allow switch statement with no cases
 
#include <vdw.h>
#include <kusb.h>
#include \"..\\AaDeviceinterface.h\"

#include \"Aa.h\"
#include \"AaDevice.h\"

#pragma hdrstop(\"Aa.pch\")

extern KTrace t; // Global driver trace object

GUID AaDevice_Guid = AaDevice_CLASS_GUID;

////////////////////////////////////////////////////////////////////////
//  AaDevice::AaDevice
//
// Routine Description:
// This is the constructor for the Functional Device Object, or FDO.
// It is derived from KPnpDevice, which builds in automatic
//    dispatching of subfunctions of IRP_MJ_POWER and IRP_MJ_PNP to
// virtual member functions.
//
// Parameters:
// Pdo - Physical Device Object - this is a pointer to a system
// device object that represents the physical device.
//
// Unit - Unit number. This is a number to append to the device\'s
// base device name to form the Logical Device Object\'s name
//
// Return Value:
// None  
//
// Comments:
// The object being constructed contains a data member (m_Lower) of type
// KPnpLowerDevice. By initializing it, the driver binds the FDO to the
// PDO and creates an interface to the upper edge of the system class driver.
//

AaDevice::AaDevice(PDEVICE_OBJECT Pdo, ULONG Unit) :
KPnpDevice(Pdo, &AaDevice_Guid)
{
t << \"Entering AaDevice::AaDevice (constructor)\\n\";


// Check constructor status
    if ( ! NT_SUCCESS(m_ConstructorStatus) )
{
   return;
}

// Remember our unit number
m_Unit = Unit;

// Initialize the lower device
m_Lower.Initialize(this, Pdo);

// Initialize the interface object.  The wizard generates code
// to support a single interface.  You may create and add additional
// interfaces.  By default, the wizard uses InterfaceNumber 0 (the
// first interface descriptor), ConfigurationValue 1 (the first
// configuration descriptor), and initial interface alternate
// setting of 0.  If your device has multiple interfaces or alternate
// settings for an interface, you can add additional KUsbInterface
// objects or adjust the parameters passed to this function.
m_Interface.Initialize(
m_Lower, //KUsbLowerDevice
0, //InterfaceNumber
1, //ConfigurationValue
0 //Initial Interface Alternate Setting
);

// Initialize each Pipe object
m_Endpoint1IN.Initialize(m_Lower, 0x81, 32);
m_Endpoint2OUT.Initialize(m_Lower, 0x2, 32);
m_Endpoint3IN.Initialize(m_Lower, 0x83, 32);
m_Endpoint4OUT.Initialize(m_Lower, 0x4, 32);
m_Endpoint5IN.Initialize(m_Lower, 0x85, 64);
m_Endpoint6OUT.Initialize(m_Lower, 0x6, 64);

    // Inform the base class of the lower edge device object
SetLowerDevice(&m_Lower);

// Initialize the PnP Policy settings to the \"standard\" policy
SetPnpPolicy();

// TODO: Customize the PnP Policy for this device by setting
// flags in m_Policies.

// Initialize the Power Policy settings to the \"standard\" policy
SetPowerPolicy();

// TODO: Customize the Power Policy for this device by setting
// flags in m_PowerPolicies.

}


////////////////////////////////////////////////////////////////////////
//  AaDevice::~AaDevice
//
// Routine Description:
// This is the destructor for the Functional Device Object, or FDO.
//
// Parameters:
// None
//
// Return Value:
// None
//
// Comments:
// None
//

AaDevice::~AaDevice()
{
t << \"Entering AaDevice::~AaDevice() (destructor)\\n\";
}

////////////////////////////////////////////////////////////////////////
//  PNPMinorFunctionName
//
// Routine Description:
// Return a string describing the Plug and Play minor function
//
// Parameters:
// mn - Minor function code
//
// Return Value:
// char * - Ascii name of minor function
//
// Comments:
// This function is used for tracing the IRPs.  Remove the function,
// or conditionalize it for debug-only builds, if you want to save
// space in the driver image.
//

char *PNPMinorFunctionName(ULONG mn)
{
static char* minors[] = {
\"IRP_MN_START_DEVICE\",
\"IRP_MN_QUERY_REMOVE_DEVICE\",
\"IRP_MN_REMOVE_DEVICE\",
\"IRP_MN_CANCEL_REMOVE_DEVICE\",
\"IRP_MN_STOP_DEVICE\",
\"IRP_MN_QUERY_STOP_DEVICE\",
\"IRP_MN_CANCEL_STOP_DEVICE\",
\"IRP_MN_QUERY_DEVICE_RELATIONS\",
\"IRP_MN_QUERY_INTERFACE\",
\"IRP_MN_QUERY_CAPABILITIES\",
\"IRP_MN_QUERY_RESOURCES\",
\"IRP_MN_QUERY_RESOURCE_REQUIREMENTS\",
\"IRP_MN_QUERY_DEVICE_TEXT\",
\"IRP_MN_FILTER_RESOURCE_REQUIREMENTS\",
\"<unknown minor function>\",
\"IRP_MN_READ_CONFIG\",
\"IRP_MN_WRITE_CONFIG\",
\"IRP_MN_EJECT\",
\"IRP_MN_SET_LOCK\",
\"IRP_MN_QUERY_ID\",
\"IRP_MN_QUERY_PNP_DEVICE_STATE\",
\"IRP_MN_QUERY_BUS_INFORMATION\",
\"IRP_MN_DEVICE_USAGE_NOTIFICATION\",
\"IRP_MN_SURPRISE_REMOVAL\"
};

if (mn > IRP_MN_SURPRISE_REMOVAL)
return \"<unknown minor function>\";
else
return minors[mn];
}

////////////////////////////////////////////////////////////////////////
//  AaDevice::DefaultPnp
//
// Routine Description:
// Default handler for IRP_MJ_PNP
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result returned from lower device
//
// Comments:
// This routine just passes the IRP through to the lower device. It is
// the default handler for IRP_MJ_PNP. IRPs that correspond to
// any virtual members of KpnpDevice that handle minor functions of
// IRP_MJ_PNP and that are not overridden get passed to this routine.
//

NTSTATUS AaDevice::DefaultPnp(KIrp I)
{
t << \"Entering AaDevice::DefaultPnp with IRP minor function=\"
 << PNPMinorFunctionName(I.MinorFunction()) << EOL;

I.ForceReuseOfCurrentStackLocationInCalldown();
return m_Lower.PnpCall(this, I);
}


////////////////////////////////////////////////////////////////////////
//  AaDevice::DefaultPower
//
// Routine Description:
// Default handler for IRP_MJ_POWER
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result returned from lower device
//
// Comments:
// This routine just passes the IRP through to the lower device. It is
// the default handler for IRP_MJ_POWER.
//

NTSTATUS AaDevice::DefaultPower(KIrp I)
{
t << \"Entering AaDevice::DefaultPower\\n\";

I.IndicatePowerIrpProcessed();
I.CopyParametersDown();
return m_Lower.PnpPowerCall(this, I);
}

////////////////////////////////////////////////////////////////////////////////
//  AaDevice::SystemControl
//
// Routine Description:
// Default handler for IRP_MJ_SYSTEM_CONTROL
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result returned from lower device
//
// Comments:
// This routine just passes the IRP through to the next device since this driver
// is not a WMI provider.
//

NTSTATUS AaDevice::SystemControl(KIrp I)
{
t << \"Entering AaDevice::SystemControl\\n\";

I.ForceReuseOfCurrentStackLocationInCalldown();
return m_Lower.PnpCall(this, I);
}

////////////////////////////////////////////////////////////////////////
//  AaDevice::OnStartDevice
//
// Routine Description:
// Handler for IRP_MJ_PNP subfcn IRP_MN_START_DEVICE
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result code
//
// Comments:
// Typically, the driver sends a SET CONFIGURATION request for the
// USB device by using KUsbLowerDevice::ActivateConfiguration with
// the ConfigurationValue to activate.  The wizard generates code to
// support a single configuration.  You may create and add additional
// configurations.
//

NTSTATUS AaDevice::OnStartDevice(KIrp I)
{
t << \"Entering AaDevice::OnStartDevice\\n\";

NTSTATUS status = STATUS_UNSUCCESSFUL;

AC_STATUS acStatus = AC_SUCCESS;

I.Information() = 0;

// The default Pnp policy has already cleared the IRP with the lower device

//By default, the wizard passes a ConfigurationValue of 1 to
//ActivateConfiguration().  This corresponds to the first configuration
//that the device reports in its configuration descriptor.  If the device
//supports multiple configurations, pass the appropriate
//ConfigurationValue of the configuration to activate here.
acStatus = m_Lower.ActivateConfiguration(
1 // ConfigurationValue 1 (the first configuration)
);

switch (acStatus)
{
case AC_SUCCESS:
t << \"USB Configuration OK\\n\";
status = STATUS_SUCCESS;
break;

case AC_COULD_NOT_LOCATE_INTERFACE:
t << \"Could not locate interface\\n\";
break;

case AC_COULD_NOT_PRECONFIGURE_INTERFACE:
t << \"Could not get configuration descriptor\\n\";
break;

case AC_CONFIGURATION_REQUEST_FAILED:
t << \"Board did not accept configuration URB\\n\";
break;

case AC_FAILED_TO_INITIALIZE_INTERFACE_OBJECT:
t << \"Failed to initialize interface object\\n\";
break;

case AC_FAILED_TO_GET_DESCRIPTOR:
t << \"Failed to get device descriptor\\n\";
break;

case AC_FAILED_TO_OPEN_PIPE_OBJECT:
//NOTE: this may not be an error.  It could mean that
//the device has an endpoint for which a KUsbPipe object has
//not been instanced.  If the intention is to not use this endpoint,
//then it\'s likely not a problem.  
status = STATUS_SUCCESS;
t << \"Failed to open pipe object\\n\";
break;

default:
t << \"Unexpected error activating USB configuration\\n\";
break;
}

   return status;  // base class completes the IRP
}


////////////////////////////////////////////////////////////////////////
//  AaDevice::OnStopDevice
//
// Routine Description:
// Handler for IRP_MJ_PNP subfcn IRP_MN_STOP_DEVICE
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result code
//
// Comments:
// The system calls this when the device is stopped.
// The driver should release any hardware resources
// in this routine.
//
// The base class passes the irp to the lower device.
//

NTSTATUS AaDevice::OnStopDevice(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;

t << \"Entering AaDevice::OnStopDevice\\n\";

m_Lower.DeActivateConfiguration();


// TODO: Add device-specific code to stop your device  

return status;

// The following macro simply allows compilation at Warning Level 4
// If you reference this parameter in the function simply remove the macro.
UNREFERENCED_PARAMETER(I);
}

////////////////////////////////////////////////////////////////////////
//  AaDevice::OnRemoveDevice
//
// Routine Description:
// Handler for IRP_MJ_PNP subfcn IRP_MN_REMOVE_DEVICE
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result code
//
// Comments:
// The system calls this when the device is removed.
// Our PnP policy will take care of
// (1) giving the IRP to the lower device
// (2) detaching the PDO
// (3) deleting the device object
//

NTSTATUS AaDevice::OnRemoveDevice(KIrp I)
{
t << \"Entering AaDevice::OnRemoveDevice\\n\";

// Device removed, release the system resources used by the USB lower device.
m_Lower.ReleaseResources();




// TODO: Add device-specific code to remove your device  

return STATUS_SUCCESS;

// The following macro simply allows compilation at Warning Level 4
// If you reference this parameter in the function simply remove the macro.
UNREFERENCED_PARAMETER(I);
}

////////////////////////////////////////////////////////////////////////
//  AaDevice::OnDevicePowerUp
//
// Routine Description:
// Handler for IRP_MJ_POWER with minor function IRP_MN_SET_POWER
// for a request to go to power on state from low power state
//
// Parameters:
// I - IRP containing POWER request
//
// Return Value:
// NTSTATUS - Status code indicating success or failure
//
// Comments:
// This routine implements the OnDevicePowerUp function.
// This function was called by the framework from the completion
// routine of the IRP_MJ_POWER dispatch handler in KPnpDevice.
// The bus driver has completed the IRP and this driver can now
// access the hardware device.  
// This routine runs at dispatch level.
//

NTSTATUS AaDevice::OnDevicePowerUp(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;

t << \"Entering AaDevice::OnDevicePowerUp\\n\";

// TODO: Service the device.
// Restore any context to the hardware device that
// was saved during the handling of a power down request.
// See the OnDeviceSleep function.
// Do NOT complete this IRP.
//
return status;

// The following macro simply allows compilation at Warning Level 4
// If you reference this parameter in the function simply remove the macro.
UNREFERENCED_PARAMETER(I);
}

////////////////////////////////////////////////////////////////////////
//  AaDevice::OnDeviceSleep
//
// Routine Description:
// Handler for IRP_MJ_POWER with minor function IRP_MN_SET_POWER
// for a request to go to a low power state from a high power state
//
// Parameters:
// I - IRP containing POWER request
//
// Return Value:
// NTSTATUS - Status code indicating success or failure
//
// Comments:
// This routine implements the OnDeviceSleep function.
// This function was called by the framework from the IRP_MJ_POWER
// dispatch handler in KPnpDevice prior to forwarding to the PDO.
// The hardware has yet to be powered down and this driver can now
// access the hardware device.  
// This routine runs at passive level.
//

NTSTATUS AaDevice::OnDeviceSleep(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;

t << \"Entering AaDevice::OnDeviceSleep\\n\";

// TODO: Service the device.
// Save any context to the hardware device that will be required
// during a power up request. See the OnDevicePowerUp function.
// Do NOT complete this IRP.  The base class handles forwarding
// this IRP to the PDO.
//
return status;

// The following macro simply allows compilation at Warning Level 4
// If you reference this parameter in the function simply remove the macro.
UNREFERENCED_PARAMETER(I);
}

////////////////////////////////////////////////////////////////////////
//  AaDevice::Create
//
// Routine Description:
// Handler for IRP_MJ_CREATE
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result code
//
// Comments:
//

NTSTATUS AaDevice::Create(KIrp I)
{
NTSTATUS status;

t << \"Entering AaDevice::Create, \" << I << EOL;

// TODO: Add driver specific create handling code here

// Generally a create IRP is targeted at our FDO, so we don\'t need
// to pass it down to the PDO.  We have found for some devices, the
// PDO is not expecting this Irp and returns an error code.
// The default wizard code, therefore completes the Irp here using
// PnpComplete().  The following commented code could be used instead
// of PnpComplete() to pass the Irp to the PDO, which would complete it.
//
// I.ForceReuseOfCurrentStackLocationInCalldown();
// status = m_Lower.PnpCall(this, I);

status = I.PnpComplete(this, STATUS_SUCCESS, IO_NO_INCREMENT);

t << \"AaDevice::Create Status \" << (ULONG)status << EOL;

return status;
}


////////////////////////////////////////////////////////////////////////
//  AaDevice::Close
//
// Routine Description:
// Handler for IRP_MJ_CLOSE
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result code
//
// Comments:
//

NTSTATUS AaDevice::Close(KIrp I)
{
NTSTATUS status;

t << \"Entering AaDevice::Close, \" << I << EOL;

// TODO: Add driver specific close handling code here

// Generally a close IRP is targeted at our FDO, so we don\'t need
// to pass it down to the PDO.  We have found for some devices, the
// PDO is not expecting this Irp and returns an error code.
// The default wizard code, therefore completes the Irp here using
// PnpComplete().  The following commented code could be used instead
// of PnpComplete() to pass the Irp to the PDO, which would complete it.
//
// I.ForceReuseOfCurrentStackLocationInCalldown();
// status = m_Lower.PnpCall(this, I);

status = I.PnpComplete(this, STATUS_SUCCESS, IO_NO_INCREMENT);

t << \"AaDevice::Close Status \" << (ULONG)status << EOL;

    return status;
}

////////////////////////////////////////////////////////////////////////
//  AaDevice::Cleanup
//
// Routine Description:
// Handler for IRP_MJ_CLEANUP
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result code
//
// Comments:
//

NTSTATUS AaDevice::CleanUp(KIrp I)
{
t << \"Entering CleanUp, \" << I << EOL;

// TODO: Insert your code to respond to the CLEANUP message.
return I.PnpComplete(this, STATUS_SUCCESS);
}


////////////////////////////////////////////////////////////////////////
//  AaDevice::Read
//
// Routine Description:
// Handler for IRP_MJ_READ
//
// Parameters:
// I Current IRP
//
// Return Value:
// NTSTATUS Result code
//
// Comments:
// This routine handles read requests.
//
// The KPnpDevice class handles restricting IRP flow
// if the device is stopping or being removed.
//

NTSTATUS AaDevice::Read(KIrp I)
{
t << \"Entering AaDevice::Read, \" << I << EOL;
// TODO: Check the incoming request.  Replace \"FALSE\" in the following
// line with a check that returns TRUE if the request is not valid.

    if (FALSE) // If (Request is invalid)
{
// Invalid parameter in the Read request
I.Information() = 0;
return I.PnpComplete(this, STATUS_INVALID_PARAMETER);
}

// Always ok to read 0 elements.
if (I.ReadSize() == 0)
{
I.Information() = 0;
return I.PnpComplete(this, STATUS_SUCCESS);
}

// Declare a memory object
KMemory Mem(I.Mdl());

    ULONG dwTotalSize = I.ReadSize(CURRENT);
ULONG dwMaxSize = m_Endpoint5IN.MaximumTransferSize();

// If the total requested read size is greater than the Maximum Transfer
// Size for the Pipe, request to read only the Maximum Transfer Size since
// the bus driver will fail an URB with a TransferBufferLength of greater
// than the Maximum Transfer Size.
if (dwTotalSize > dwMaxSize)
{
ASSERT(dwMaxSize);
dwTotalSize = dwMaxSize;
}

// Allocate a new context structure for Irp completion
USB_COMPLETION_INFO* pCompInfo = new (NonPagedPool) USB_COMPLETION_INFO;
if (pCompInfo == NULL)
{
I.Information() = 0;
return I.PnpComplete(this, STATUS_INSUFFICIENT_RESOURCES);
}

// TODO: Select the correct pipe to read from

// Create an URB to do actual Bulk read from the pipe
PURB pUrb = m_Endpoint5IN.BuildBulkTransfer(
    Mem,       // Where is data coming from?
dwTotalSize,   // How much data to read?
TRUE,         // direction (TRUE = IN)
NULL, // Link to next URB
TRUE // Allow a short transfer
);        

if (pUrb == NULL)
{
delete pCompInfo;
I.Information() = 0;
return I.PnpComplete(this, STATUS_INSUFFICIENT_RESOURCES);
}

// Initialize context structure
pCompInfo->m_pClass = this;
pCompInfo->m_pUrb = pUrb;

    // Submit the URB to our USB device
NTSTATUS status;
status = m_Endpoint5IN.SubmitUrb(I, pUrb, LinkTo(ReadComplete), pCompInfo, 0);
return status;
}

////////////////////////////////////////////////////////////////////////
//  AaDevice::ReadComplete
//
// Routine Description:
// Completion Handler for IRP_MJ_READ
//
// Parameters:
// I - IRP just completed by USB
// pContext - Context structure containing pointer to Urb
//
// Parameters:
// NTSTATUS - STATUS_SUCCESS
//
// Comments:
// This routine is called when USBD completes the read request
//

NTSTATUS AaDevice::ReadComplete(KIrp I, USB_COMPLETION_INFO* pContext)
{
// Normal completion routine code to propagate pending flag

if (I->PendingReturned)
{
I.MarkPending();
}

NTSTATUS status = I.Status();
PURB pUrb = pContext->m_pUrb;
ULONG nBytesRead = 0;

if ( NT_SUCCESS(status) )
{
nBytesRead = pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;
if (nBytesRead > 0)
t << \"Read() got \" << nBytesRead<< \" bytes from USB\\n\";
    }

// Deallocate Urb and context structure
delete pUrb;
delete pContext;

// set returned count
I.Information() = nBytesRead;

// Plug and Play accounting
DecrementOutstandingRequestCount();

// allow IRP completion processing
return STATUS_SUCCESS;
}

////////////////////////////////////////////////////////////////////////
//  AaDevice::Write
//
// Routine Description:
// Handler for IRP_MJ_WRITE
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result code
//
// Comments:
// This routine handles write requests.
//
// The KPnpDevice class handles restricting IRP flow
// if the device is stopping or being removed.
//

NTSTATUS AaDevice::Write(KIrp I)
{
t << \"Entering AaDevice::Write, \" << I << EOL;
// TODO: Check the incoming request.  Replace \"FALSE\" in the following
// line with a check that returns TRUE if the request is not valid.
    if (FALSE)
{
// Invalid parameter in the Write request
I.Information() = 0;
return I.PnpComplete(this, STATUS_INVALID_PARAMETER);
}

// Always ok to write 0 elements.
if (I.WriteSize() == 0)
{
I.Information() = 0;
return I.PnpComplete(this, STATUS_SUCCESS);
}
ULONG dwTotalSize = I.WriteSize(CURRENT);
ULONG dwMaxSize = m_Endpoint6OUT.MaximumTransferSize();

// If the total requested read size is greater than the Maximum Transfer
// Size for the Pipe, request to read only the Maximum Transfer Size since
// the bus driver will fail an URB with a TransferBufferLength of greater
// than the Maximum Transfer Size.
if (dwTotalSize > dwMaxSize)
{
ASSERT(dwMaxSize);
dwTotalSize = dwMaxSize;
}

// Declare a memory object
KMemory Mem(I.Mdl());

// Allocate a new context structure for Irp completion
USB_COMPLETION_INFO* pCompInfo = new (NonPagedPool) USB_COMPLETION_INFO;
if (pCompInfo == NULL)
{
I.Information() = 0;
return I.PnpComplete(this, STATUS_INSUFFICIENT_RESOURCES);
}

// TODO: Select the correct pipe to write to

// Create an URB to do actual Bulk write to the pipe
PURB pUrb = m_Endpoint6OUT.BuildBulkTransfer(
Mem,          // Where is data coming from?
dwTotalSize,  // How much data to read?
FALSE,        // direction (FALSE = OUT)
NULL  // Link to next URB
);        

if (pUrb == NULL)
{
delete pCompInfo;
I.Information() = 0;
return I.PnpComplete(this, STATUS_INSUFFICIENT_RESOURCES);
}

// Initialize context structure
pCompInfo->m_pClass = this;
pCompInfo->m_pUrb = pUrb;

    // Submit the URB to our USB device
NTSTATUS status;
status = m_Endpoint6OUT.SubmitUrb(I, pUrb, LinkTo(WriteComplete), pCompInfo, 0);
return status;
}

////////////////////////////////////////////////////////////////////////
//  AaDevice::WriteComplete
//
// Routine Description:
// Completion Handler for IRP_MJ_WRITE
//
// Parameters:
// I - IRP just completed by USB
// pContext - Context structure containing pointer to Urb
//
// Return Value:
// NTSTATUS STATUS_SUCCESS
//
// Comments:
// This routine is called when USBD completes the write request
//

NTSTATUS AaDevice::WriteComplete(KIrp I, USB_COMPLETION_INFO* pContext)
{
// Normal completion routine code to propagate pending flag

if (I->PendingReturned)
{
I.MarkPending();
}

NTSTATUS status = I.Status();
PURB pUrb = pContext->m_pUrb;
ULONG nBytesWritten = 0;

if ( NT_SUCCESS(status) )
{
nBytesWritten = pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;
if (nBytesWritten > 0)
t << \"Wrote \" << nBytesWritten << \" bytes to USB\\n\";
    }

// Deallocate Urb and context structure
delete pUrb;
delete pContext;

// set returned count
I.Information() = nBytesWritten;

// Plug and Play accounting
DecrementOutstandingRequestCount();

// allow IRP completion processing
return STATUS_SUCCESS;
}

////////////////////////////////////////////////////////////////////////
//  AaDevice::DeviceControl
//
// Routine Description:
// Handler for IRP_MJ_DEVICE_CONTROL
//
// Parameters:
// I - Current IRP
//
// Return Value:
// None
//
// Comments:
// This routine is the first handler for Device Control requests.
// The KPnpDevice class handles restricting IRP flow
// if the device is stopping or being removed.
//

NTSTATUS AaDevice::DeviceControl(KIrp I)
{
NTSTATUS status;

t << \"Entering AaDevice::Device Control, \" << I << EOL;
switch (I.IoctlCode())
{
default:
// Unrecognized IOCTL request
status = STATUS_INVALID_PARAMETER;
break;
}

// If the IRP\'s IOCTL handler deferred processing using some driver
// specific scheme, the status variable is set to STATUS_PENDING.
// In this case we simply return that status, and the IRP will be
// completed later.  Otherwise, complete the IRP using the status
// returned by the IOCTL handler.
if (status == STATUS_PENDING)
{
return status;
}
else
{
return I.PnpComplete(this, status);
}
}




学习,学习,再学习 努力,努力,常努力 真的需要大家的帮助
zd001
驱动牛犊
驱动牛犊
  • 注册日期2001-10-12
  • 最后登录2004-09-30
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2002-05-26 14:35
// Aa.cpp
//
// Generated by DriverWizard version DriverStudio 2.6.0 (Build 336)
// Requires Compuware\'s DriverWorks classes
//

#define VDW_MAIN
#include <vdw.h>
#include <kusb.h>
#include \"Aa.h\"
#include \"AaDevice.h\"

#pragma hdrstop(\"Aa.pch\")

// Generated by DriverWizard version DriverStudio 2.6.0 (Build 336)

// Set a default 32-bit tag value to be stored with each heap block
// allocated by operator new. Use BoundsChecker to view the memory pool.
// This value can be overridden using the global function SetPoolTag().
POOLTAG DefaultPoolTag(\'  aA\');

// Create the global driver trace object
// TODO: Use KDebugOnlyTrace if you want trace messages
// to appear only in debug builds.  Use KTrace if
// you want trace messages to always appear.
KTrace t(\"Aa\");

/////////////////////////////////////////////////////////////////////
// Begin INIT section
#pragma code_seg(\"INIT\")

DECLARE_DRIVER_CLASS(Aa, NULL)

/////////////////////////////////////////////////////////////////////
//  Aa::DriverEntry
//
// Routine Description:
// This is the first entry point called by the system when the
// driver is loaded.
//
// Parameters:
// RegistryPath - String used to find driver parameters in the
// registry.  To locate Aa look for:
// HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Aa
//
// Return Value:
// NTSTATUS - Return STATUS_SUCCESS if no errors are encountered.
// Any other indicates to the system that an error has occured.
//
// Comments:
//

NTSTATUS Aa::DriverEntry(PUNICODE_STRING RegistryPath)
{
t << \"In DriverEntry\\n\";


// Open the \"Parameters\" key under the driver
KRegistryKey Params(RegistryPath, L\"Parameters\");
if ( NT_SUCCESS(Params.LastError()) )
{
#if DBG
ULONG bBreakOnEntry = FALSE;
// Read \"BreakOnEntry\" value from registry
Params.QueryValue(L\"BreakOnEntry\", &bBreakOnEntry);
// If requested, break into debugger
if (bBreakOnEntry) DbgBreakPoint();
#endif
// Load driver data members from the registry
LoadRegistryParameters(Params);
}
m_Unit = 0;

return STATUS_SUCCESS;
}


/////////////////////////////////////////////////////////////////////
//  Aa::LoadRegistryParameters
//
// Routine Description:
// Load driver data members from the registry.
//
// Parameters:
// Params - Open registry key pointing to \"Parameters\"
//
// Return Value:
// None
//
// Comments:
// Member variables are updated with values read from registry.
//
// The parameters are found as values under the \"Parameters\" key,
// HKLM\\SYSTEM\\CurrentControlSet\\Services\\Aa\\Parameters\\...
//

void Aa::LoadRegistryParameters(KRegistryKey &Params)
{

m_bBreakOnEntry = FALSE;
Params.QueryValue(L\"BreakOnEntry\", &m_bBreakOnEntry);
t << \"m_bBreakOnEntry loaded from registry, resulting value: [\" << m_bBreakOnEntry << \"]\\n\";

}
// End INIT section
/////////////////////////////////////////////////////////////////////
#pragma code_seg()

/////////////////////////////////////////////////////////////////////
//  Aa::AddDevice
//
// Routine Description:
// Called when the system detects a device for which this
// driver is responsible.
//
// Parameters:
// Pdo - Physical Device Object. This is a pointer to a system device
// object that represents the physical device.
//
// Return Value:
// NTSTATUS - Success or failure code.
//
// Comments:
// This function creates the Functional Device Object, or FDO. The FDO
// enables this driver to handle requests for the physical device.
//

NTSTATUS Aa::AddDevice(PDEVICE_OBJECT Pdo)
{
t << \"AddDevice called\\n\";

    // Create the device object. Note that we used a form of \"placement\" new,
// that is a member operator of KDevice.  This form will use storage
// allocated by the system in the device object\'s device to store our
// class instance.
AaDevice * pDevice = new (
static_cast<PCWSTR>(KUnitizedName(L\"AaDevice\", m_Unit)),
FILE_DEVICE_UNKNOWN,
NULL,
0,
DO_DIRECT_IO
| DO_POWER_PAGABLE
)
AaDevice(Pdo, m_Unit);

if (pDevice == NULL)
{                                                                                                                                                                                                      
t << \"Error creating device AaDevice\"
  << (ULONG) m_Unit << EOL;
   return STATUS_INSUFFICIENT_RESOURCES;
}

NTSTATUS status = pDevice->ConstructorStatus();

if ( !NT_SUCCESS(status) )
{
t << \"Error constructing device AaDevice\"
 << (ULONG) m_Unit << \" status \" << (ULONG) status << EOL;
delete pDevice;
}                                                                                                                                
else
{
m_Unit++;

pDevice->ReportNewDevicePowerState(PowerDeviceD0);
}

return status;
}
学习,学习,再学习 努力,努力,常努力 真的需要大家的帮助
zd001
驱动牛犊
驱动牛犊
  • 注册日期2001-10-12
  • 最后登录2004-09-30
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-05-26 18:40
请高人告诉我呀,很着急,此问题折磨的时间太久了!!!
学习,学习,再学习 努力,努力,常努力 真的需要大家的帮助
zd001
驱动牛犊
驱动牛犊
  • 注册日期2001-10-12
  • 最后登录2004-09-30
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2002-05-27 15:03
请帮忙救我!!!
学习,学习,再学习 努力,努力,常努力 真的需要大家的帮助
hsr321
驱动牛犊
驱动牛犊
  • 注册日期2002-05-17
  • 最后登录2004-07-30
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2002-05-27 18:40
这么多,慢慢看看 ;)有空吗。。。
cqzhl
驱动牛犊
驱动牛犊
  • 注册日期2002-01-29
  • 最后登录2007-03-21
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2002-05-27 19:40
后面的PIPE信息没有.是因为设备没有被正确的配置。
在AaDevice::AaDevice(PDEVICE_OBJECT Pdo, ULONG Unit)
中使用m_Lower.ActivateConfiguration(0)即可。(参数为要启用的配置号)
如果还不行,那就是DS不认配置描述符。(在DS中如果设备有2个描述符,
那么它就只查找配置号为0和1的描述符。如果设备只有一个描述符,且配置号
不是0,那么activeconfig就会返回一个错误,报告没有该描述符)这时,可以用以下的
办法进行配置:
m_lower.preconfig()
PUSB_INTERFACE_DESCRIPTOR pInterfaceDescriptor=null;
PUSB_ENDPOINT_DESCRIPTOR pEndpoint
m_Lower.PreconfigureInterface(&pInterfaceDescriptor,&pEndpoint)
m_Lower.Configure()
huak
驱动牛犊
驱动牛犊
  • 注册日期2002-03-31
  • 最后登录2002-06-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2002-05-28 10:30
我做的也是差不多的东西
用的也是ds
我想问一下
程序里有好多 TODO不用管吗?
read 子程序中的
false提示要用I.xxx代替
但是结构不太清楚
这个地方需要改动吗?应该用什么呢?
请指点
还有就是装上去之后显示一个黄色的问号
为什么呢?
上面那位大侠好像说得很有道理
我去试试
多谢
zd001
驱动牛犊
驱动牛犊
  • 注册日期2001-10-12
  • 最后登录2004-09-30
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2002-05-28 11:26
谢谢CQZHL,我试试看
学习,学习,再学习 努力,努力,常努力 真的需要大家的帮助
huak
驱动牛犊
驱动牛犊
  • 注册日期2002-03-31
  • 最后登录2002-06-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2002-05-30 09:37
我的东西只有一个配置号为1的配置

请问我用大侠所提供的第二种方法

编译不能通过

为什么

还有上面那位仁兄如果成功的话
能否告诉我一点经验

多谢了!!!
zd001
驱动牛犊
驱动牛犊
  • 注册日期2001-10-12
  • 最后登录2004-09-30
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2002-05-30 10:19
谢谢cqzhl大侠,真的如你所说,用m_Lower.ActivateConfiguration(0)即可,看来还得多学习DS的有关资料。上面的朋友,你用这方法试试,应该有效的。
学习,学习,再学习 努力,努力,常努力 真的需要大家的帮助
huak
驱动牛犊
驱动牛犊
  • 注册日期2002-03-31
  • 最后登录2002-06-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2002-05-30 11:30
谢谢
我试了一下
还是不行
总是提示不能打开设备句柄
我发现我和你的驱动程序差不多
不知道问题出在哪里
1,请问你的vid和pid是怎么处理的?
2,装上去之后显示应该不是一个黄色的问号,而是和原来usb controler一样的吧?
3,除了这个地方,对ds生成的你还在哪里作了修改,我看你贴在上面的好像都没有改。
4,直接用ds生成的test就可以实现数据传输吧?
5,guid是不是用ds生成的?

多谢呀!!!
huak
驱动牛犊
驱动牛犊
  • 注册日期2002-03-31
  • 最后登录2002-06-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2002-05-30 11:34
用工具看发现描述表信息只有第一部分

这里的工具是什么呀〉?
谢谢
zd001
驱动牛犊
驱动牛犊
  • 注册日期2001-10-12
  • 最后登录2004-09-30
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2002-05-31 07:38
    如果你的驱动安装后提示设备不能启动或正常工作,那么表明你的驱动或固件起码有一个有问题,驱动安装后如果PC提示设备正常工作在TEST里面才有打开设备的可能,在我看来是你的驱动有问题。工具可以是USBVIEW,不是在DDK里就是在DS里面,也可以用WINDRIVER看,也可以到USB.ORG下载测试软件。加油
学习,学习,再学习 努力,努力,常努力 真的需要大家的帮助
游客

返回顶部