Developers

Developers

Here is a code snippet that may be of use to some of you developers out there. We have shared it here because others have not or similar solutions in the public domain were lacking.

All code is provided without warranty so use at your own discretion. We also cannot offer support in regard to these code snippets.

Spin Down a USB Hard Disk

Unfortunately when using most external USB hard disks with Windows, Windows fails to spin down the disk when it is not in use wasting power and causing unnecessary wear. This C++ code snippet provides a function that allows you to start and stop (spin down) SCSI compatible devices such as an external USB hard disk. Developers can use this code in their applications to improve how drives are managed.

/**************************************************************/
/* SCSI Start Stop Unit C++ Code Snippet by KnowledgeIT 2007  */
/**************************************************************/
#include <windows.h>

#ifndef IOCTL_SCSI_PASS_THROUGH_DIRECT

#define IOCTL_SCSI_PASS_THROUGH_DIRECT 0x4D014
#define SCSI_IOCTL_DATA_OUT 0
#define SCSI_IOCTL_DATA_IN 1
#define SCSI_IOCTL_DATA_UNSPECIFIED 2

typedef struct _SCSI_PASS_THROUGH_DIRECT 
{
	USHORT Length;
	UCHAR ScsiStatus;
	UCHAR PathId;
	UCHAR TargetId;
	UCHAR Lun;
	UCHAR CdbLength;
	UCHAR SenseInfoLength;
	UCHAR DataIn;
	ULONG DataTransferLength;
	ULONG TimeOutValue;
	PVOID DataBuffer;
	ULONG SenseInfoOffset;
	UCHAR Cdb[16];
} SCSI_PASS_THROUGH_DIRECT, *PSCSI_PASS_THROUGH_DIRECT;

#endif 



#pragma pack(1)

#define SCSIOP_START_STOP_UNIT 0x1B

typedef struct _CDB_START_STOP_UNIT 
{
	UCHAR OperationCode; // 0x1B - SCSIOP_START_STOP_UNIT
	UCHAR Immediate : 1;
	UCHAR Reserved1 : 4;
	UCHAR Lun : 3;
	UCHAR Reserved2[2];
	UCHAR Start : 1;
	UCHAR LoadEject : 1;
	UCHAR Reserved3 : 2;
	UCHAR PowerCondition : 4;
	UCHAR Control;
} CDB_START_STOP_UNIT;

#pragma pack()

BOOL SendCBD(HANDLE device, void *cdb, UCHAR cdb_length, void *buffer, DWORD buffer_length, int data_in = SCSI_IOCTL_DATA_IN)
{
	DWORD returned;
	
	// size of SCSI_PASS_THROUGH + 96 bytes for sense data
	unsigned char cmd[sizeof(SCSI_PASS_THROUGH_DIRECT) + 96] = {0};
	
	SCSI_PASS_THROUGH_DIRECT *pcmd = (SCSI_PASS_THROUGH_DIRECT *) cmd;
	
	// Copy the CDB to the SCSI_PASS_THROUGH structure
	memcpy(pcmd->Cdb, cdb, cdb_length);
	
	pcmd->DataBuffer = buffer;
	pcmd->DataTransferLength = buffer_length;
	pcmd->DataIn = data_in;
	pcmd->CdbLength = cdb_length;
	pcmd->Length = sizeof(SCSI_PASS_THROUGH_DIRECT);
	pcmd->SenseInfoLength = sizeof(cmd) - sizeof(SCSI_PASS_THROUGH_DIRECT);
	pcmd->SenseInfoOffset = sizeof(SCSI_PASS_THROUGH_DIRECT);
	pcmd->TimeOutValue = 6000;
	
	return DeviceIoControl( 	device, 
				IOCTL_SCSI_PASS_THROUGH_DIRECT, 
				(LPVOID)&cmd, 
				sizeof(cmd), 
				(LPVOID)&cmd, 
				sizeof(cmd), 
				&returned, 
				NULL);
}


BOOL ScsiStartStopUnit(CHAR dev, BOOL start)
{
	CHAR tmp[20];
	HANDLE device;
	BOOL ret;
	
	sprintf(tmp,"\\\\.\\%c:",dev);
	device = ::CreateFile(	tmp, 
				GENERIC_READ | GENERIC_WRITE, 
				FILE_SHARE_READ | FILE_SHARE_WRITE,
				NULL,
				OPEN_EXISTING, 
				0,
				0);
	
	if (device == (HANDLE)-1)
		return FALSE;
	
	CDB_START_STOP_UNIT req = {0};
	
	req.OperationCode = SCSIOP_START_STOP_UNIT;
	req.Immediate = 1;
	req.Start = start ? 1 : 0;
	
	ret = SendCBD(device, &req, sizeof(req), NULL, 0);
	
	::CloseHandle(device);
	
	return ret;
}

Latest News


Vicar tells churchgoers to swear more20:08 31/7/2010, NEWS.com.au | Breaking News
A CHURCH of England vicar told his flock to get more &quot;streetwise&quot; and swear more.

Hundreds gather for Clinton wedding19:12 31/7/2010, NEWS.com.au | Breaking News
CHELSEA Clinton is poised to marry her longtime boyfriend at an exclusive estate along New York's Hudson River.

Warm and Cosy Brick $240,00010:47 16/7/2010, Jackson Livestock & Property Listings
This warm northern aspect brick home has 3 bedrooms all with built in wardrobes, an open kitchen / dining / living area with a very warm wood heater as well as a large rumpus room. There is a fully fenced yard and double colourbond garage on a 822 sq m block.

Quality and Style $215,00010:43 15/7/2010, Jackson Livestock & Property Listings
If your taste is for a new house but your pocket says second hand then this may be the house for you. Featuring front entrance covered portal, front door panel glass entrace foyer, 3 bedrooms off access hallway, central bathroom, sun drenched large lounge/living...

Rural Property Investment Opportunity in Australia20:00 24/8/2009, Jackson Livestock & Property News
Jackson Livestock and Property are now the marketing agents for MacQuarie Valley Investments who are a freehold company that puts large parcels of freehold farming, grazing and irrigation land together. We can also organise A Grade management for all of these enterprises....

About Us | Privacy Policy | Contact Us | © 2009 Knowledge & Infomation Technology Pty. Ltd. ACN 100 580 194