McWalker Posted January 25, 2007 Share Posted January 25, 2007 I saw some posts here which are about auto eject USB. But is it possible for the script inside a USB thumb drive run till end and also eject the thumb drive from the computer? Link to comment Share on other sites More sharing options...
icemax Posted June 29, 2007 Share Posted June 29, 2007 (edited) helo deveject unmounts ("eject") your usb mass-storage device tips : source code : integrate in your script download from : ftp://ftp.heise.de/pub/ct/listings/0316-208.zip info : devEject -- Geräte automatisch abmelden, für Windows 2000/XP/2003 ================================================================= DevEject dient dazu, externe Speichergeräte wie FireWire-Platten oder USB-Sticks programmgesteuert beim Betriebssystem abzumelden. Eine nähere Beschreibung finden Sie in c't 16/03, S. 208. DevEject.exe -- das ausführbare Programm DevEject.cpp -- Quelltext in C++ the !code! -> deveject.cpp expandcollapse popup// DevEject.cpp // Plug&Play-Geräte automatisch abmelden, für Windows 2000/XP/2003 // Übersetzen mit Visual C++: // cl deveject.cpp advapi32.lib // 2003 c't/Matthias Withopf #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <stdio.h> class TDeviceEject { public: typedef enum { deec_Ok = 0, deec_UnsupportedOS = 1, deec_ErrorLoadingLibrary = 2, deec_LibraryFunctionMissing = 3, deec_DeviceNotFound = 4, deec_DeviceNotRemovable = 5, deec_DeviceHasProblem = 6, deec_NativeError = 7, deec_ErrorGettingDevNodeStatus = 8, deec_ErrorGettingDeviceIdSize = 9, deec_ErrorGettingDeviceId = 10, deec_ErrorGettingChild = 11, deec_ErrorGettingSibling = 12, deec_ErrorLocatingDevNode = 13, deec_ErrorDeviceEject = 14, deec_ErrorEjectVetoed = 15, deec_LAST } TDeviceEjectErrorCode; TDeviceEjectErrorCode DeviceEjectErrorCode; // Fehlercodes des Configuration Managers enum { CR_SUCCESS = 0x00, CR_DEFAULT = 0x01, CR_OUT_OF_MEMORY = 0x02, CR_INVALID_POINTER = 0x03, CR_INVALID_FLAG = 0x04, CR_INVALID_DEVNODE = 0x05, CR_INVALID_RES_DES = 0x06, CR_INVALID_LOG_CONF = 0x07, CR_INVALID_ARBITRATOR = 0x08, CR_INVALID_NODELIST = 0x09, CR_DEVNODE_HAS_REQS = 0x0A, CR_INVALID_RESOURCEID = 0x0B, CR_DLVXD_NOT_FOUND = 0x0C, CR_NO_SUCH_DEVNODE = 0x0D, CR_NO_MORE_LOG_CONF = 0x0E, CR_NO_MORE_RES_DES = 0x0F, CR_ALREADY_SUCH_DEVNODE = 0x10, CR_INVALID_RANGE_LIST = 0x11, CR_INVALID_RANGE = 0x12, CR_FAILURE = 0x13, CR_NO_SUCH_LOGICAL_DEV = 0x14, CR_CREATE_BLOCKED = 0x15, CR_NOT_SYSTEM_VM = 0x16, CR_REMOVE_VETOED = 0x17, CR_APM_VETOED = 0x18, CR_INVALID_LOAD_TYPE = 0x19, CR_BUFFER_SMALL = 0x1A, CR_NO_ARBITRATOR = 0x1B, CR_NO_REGISTRY_HANDLE = 0x1C, CR_REGISTRY_ERROR = 0x1D, CR_INVALID_DEVICE_ID = 0x1E, CR_INVALID_DATA = 0x1F, CR_INVALID_API = 0x20, CR_DEVLOADER_NOT_READY = 0x21, CR_NEED_RESTART = 0x22, CR_NO_MORE_HW_PROFILES = 0x23, CR_DEVICE_NOT_THERE = 0x24, CR_NO_SUCH_VALUE = 0x25, CR_WRONG_TYPE = 0x26, CR_INVALID_PRIORITY = 0x27, CR_NOT_DISABLEABLE = 0x28, CR_FREE_RESOURCES = 0x29, CR_QUERY_VETOED = 0x2A, CR_CANT_SHARE_IRQ = 0x2B, CR_NO_DEPENDENT = 0x2C, CR_SAME_RESOURCES = 0x2D, CR_NO_SUCH_REGISTRY_KEY = 0x2E, CR_INVALID_MACHINENAME = 0x2F, CR_REMOTE_COMM_FAILURE = 0x30, CR_MACHINE_UNAVAILABLE = 0x31, CR_NO_CM_SERVICES = 0x32, CR_ACCESS_DENIED = 0x33, CR_CALL_NOT_IMPLEMENTED = 0x34, CR_INVALID_PROPERTY = 0x35, CR_DEVICE_INTERFACE_ACTIVE = 0x36, CR_NO_SUCH_DEVICE_INTERFACE = 0x37, CR_INVALID_REFERENCE_STRING = 0x38, CR_INVALID_CONFLICT_LIST = 0x39, CR_INVALID_INDEX = 0x3A, CR_INVALID_STRUCTURE_SIZE = 0x3B }; DWORD NativeErrorCode; TDeviceEject(BOOL AVerbose,BOOL ADebug); ~TDeviceEject(); TDeviceEjectErrorCode Eject(PCHAR EjectDevSpec,BOOL EjectDevSpecIsName,PDWORD NativeErrorCode,PDWORD EjectedCount); static BOOL GetDriveDeviceId(PCHAR DriveSpec,PCHAR DeviceId,DWORD MaxDeviceIdSize); private: BOOL Verbose; BOOL Debug; HMODULE Lib; BOOL UnloadLib; typedef DWORD DEVINST,*PDEVINST; typedef CHAR *DEVINSTID_A; typedef enum { PNP_VetoTypeUnknown, PNP_VetoLegacyDevice, PNP_VetoPendingClose, PNP_VetoWindowsApp, PNP_VetoWindowsService, PNP_VetoOutstandingOpen, PNP_VetoDevice, PNP_VetoDriver, PNP_VetoIllegalDeviceRequest, PNP_VetoInsufficientPower, PNP_VetoNonDisableable, PNP_VetoLegacyDriver, PNP_VetoInsufficientRights } PNP_VETO_TYPE,* PPNP_VETO_TYPE; enum { DN_REMOVABLE = 0x00004000 }; typedef DWORD CONFIGRET; typedef CONFIGRET (WINAPI *TCM_Locate_DevNodeA) (OUT PDEVINST pdnDevInst,IN DEVINSTID_A pDeviceID,OPTIONAL IN ULONG ulFlags); typedef CONFIGRET (WINAPI *TCM_Get_Child) (OUT PDEVINST pdnDevInst,IN DEVINST dnDevInst,IN ULONG ulFlags); typedef CONFIGRET (WINAPI *TCM_Get_Sibling) (OUT PDEVINST pdnDevInst,IN DEVINST DevInst,IN ULONG ulFlags); typedef CONFIGRET (WINAPI *TCM_Get_DevNode_Status) (OUT PULONG pulStatus,OUT PULONG pulProblemNumber,IN DEVINST dnDevInst,IN ULONG ulFlags); typedef CONFIGRET (WINAPI *TCM_Get_Device_ID_Size) (OUT PULONG pulLen,IN DEVINST dnDevInst,IN ULONG ulFlags); typedef CONFIGRET (WINAPI *TCM_Get_Device_IDA) (IN DEVINST dnDevInst,OUT PCHAR Buffer,IN ULONG BufferLen,IN ULONG ulFlags); typedef CONFIGRET (WINAPI *TCM_Request_Device_EjectA)(IN DEVINST dnDevInst,OUT PPNP_VETO_TYPE pVetoType,OUT LPSTR pszVetoName,IN ULONG ulNameLength,IN ULONG ulFlags); TCM_Locate_DevNodeA Func_LocateDevNode; TCM_Get_Child Func_GetChild; TCM_Get_Sibling Func_GetSibling; TCM_Get_DevNode_Status Func_GetDevNodeStatus; TCM_Get_Device_ID_Size Func_GetDeviceIDSize; TCM_Get_Device_IDA Func_GetDeviceID; TCM_Request_Device_EjectA Func_RequestDeviceEject; typedef struct _TEnumDeviceInfo { struct _TEnumDeviceInfo *Parent; DEVINST DevInst; ULONG Status; ULONG ProblemNumber; } TEnumDeviceInfo,* PEnumDeviceInfo; TDeviceEjectErrorCode EnumDevices(PEnumDeviceInfo ParentEnumDeviceInfo,PDWORD EjectDeviceFound,PCHAR EjectDevSpec,BOOL EjectDevSpecIsName,DEVINST DevInst,int Indent,PDWORD NativeErrorCode); BOOL GetFriendlyName(PCHAR DeviceId,PCHAR Name,DWORD MaxNameSize); }; typedef TDeviceEject * PDeviceEject; TDeviceEject::TDeviceEject(BOOL AVerbose,BOOL ADebug) { DeviceEjectErrorCode = deec_Ok; NativeErrorCode = 0; Verbose = AVerbose; Debug = ADebug; Lib = NULL; UnloadLib = FALSE; Func_LocateDevNode = NULL; Func_GetChild = NULL; Func_GetSibling = NULL; Func_GetDevNodeStatus = NULL; Func_GetDeviceIDSize = NULL; Func_GetDeviceID = NULL; Func_RequestDeviceEject = NULL; BOOL OSOk = FALSE; DWORD V = GetVersion(); if (!(V & 0x80000000)) { BYTE MajorVersion = (BYTE)V; if (MajorVersion >= 5) OSOk = TRUE; } if (!OSOk) DeviceEjectErrorCode = deec_UnsupportedOS; else { const PCHAR LibFileName = "setupapi.dll"; Lib = GetModuleHandle(LibFileName); if (!Lib) { Lib = LoadLibrary(LibFileName); if (Lib) UnloadLib = TRUE; } if (!Lib) { DeviceEjectErrorCode = deec_ErrorLoadingLibrary; NativeErrorCode = GetLastError(); } else { Func_LocateDevNode = (TCM_Locate_DevNodeA) GetProcAddress(Lib,"CM_Locate_DevNodeA"); Func_GetChild = (TCM_Get_Child) GetProcAddress(Lib,"CM_Get_Child"); Func_GetSibling = (TCM_Get_Sibling) GetProcAddress(Lib,"CM_Get_Sibling"); Func_GetDevNodeStatus = (TCM_Get_DevNode_Status) GetProcAddress(Lib,"CM_Get_DevNode_Status"); Func_GetDeviceIDSize = (TCM_Get_Device_ID_Size) GetProcAddress(Lib,"CM_Get_Device_ID_Size"); Func_GetDeviceID = (TCM_Get_Device_IDA) GetProcAddress(Lib,"CM_Get_Device_IDA"); Func_RequestDeviceEject = (TCM_Request_Device_EjectA)GetProcAddress(Lib,"CM_Request_Device_EjectA"); } } } TDeviceEject::~TDeviceEject() { if (Lib && UnloadLib) FreeLibrary(Lib); } BOOL TDeviceEject::GetDriveDeviceId(PCHAR DriveSpec,PCHAR DeviceId,DWORD MaxDeviceIdSize) { BOOL Result = FALSE; if (DeviceId && MaxDeviceIdSize) DeviceId[0] = ''; if (DriveSpec && DriveSpec[0] && DeviceId && MaxDeviceIdSize) { HKEY Key; LONG L = RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SYSTEM\\MountedDevices",0,KEY_QUERY_VALUE,&Key); if (L == ERROR_SUCCESS) { DWORD Type; BYTE Value[1024]; DWORD ValueSize = sizeof Value; CHAR ValueName[256]; strcpy(ValueName,"\\DosDevices\\"); strncat(ValueName,DriveSpec,sizeof ValueName - 1); ValueName[sizeof ValueName - 1] = ''; L = RegQueryValueEx(Key,ValueName,0,&Type,(BYTE *)Value,&ValueSize); RegCloseKey(Key); if ((L == ERROR_SUCCESS) && (Type == REG_BINARY)) { // Beispielsweise: // \??\SBP2#API-903-95__&1394_Storage_+_Repeater_&LUN0#0050c564500068e2#{53f5630d-b6bf-11d0-94f2-00a0c91efb8b} // -> // SBP2\API-903-95__&1394_STORAGE_+_REPEATER_&LUN0050C564500068E2 PWSTR p1 = (PWSTR)Value; ValueSize /= sizeof *p1; if ((p1[0] == '\\') && (p1[1] == '?') && (p1[2] == '?') && (p1[3] == '\\')) { Result = TRUE; p1 += 4; ValueSize -= 4; PCHAR p2 = DeviceId; for (unsigned int i = 0;i < ValueSize;++i) { CHAR c = p1[i]; if ((c == '{') || ((c == '#') && (p1[i + 1] == '{'))) break; if (c == '#') c = '\\'; if ((p2 - DeviceId) < (MaxDeviceIdSize - 1)) *p2++ = c; } *p2 = ''; } } } } return Result; } BOOL TDeviceEject::GetFriendlyName(PCHAR DeviceId,PCHAR Name,DWORD MaxNameSize) { BOOL Result = FALSE; if (Name && MaxNameSize) Name[0] = ''; if (DeviceId && DeviceId[0] && Name && MaxNameSize) { HKEY Key; CHAR KeyName[1024]; strcpy(KeyName,"SYSTEM\\CurrentControlSet\\Enum\\"); strncat(KeyName,DeviceId,sizeof KeyName - 1); KeyName[sizeof KeyName - 1] = ''; LONG L = RegOpenKeyEx(HKEY_LOCAL_MACHINE,KeyName,0,KEY_QUERY_VALUE,&Key); if (L == ERROR_SUCCESS) { DWORD Type; BYTE Value[1024]; DWORD ValueSize = sizeof Value; L = RegQueryValueEx(Key,"FriendlyName",0,&Type,(BYTE *)Value,&ValueSize); if (L != ERROR_SUCCESS) L = RegQueryValueEx(Key,"DeviceDesc",0,&Type,(BYTE *)Value,&ValueSize); RegCloseKey(Key); if ((L == ERROR_SUCCESS) && (Type == REG_SZ)) { strncpy(Name,(PCHAR)Value,MaxNameSize - 1); Name[MaxNameSize - 1] = ''; Result = TRUE; } } } return Result; } static BOOL CompareWithWildcard(PCHAR s1,PCHAR s2) { if (s1 && s2) for (;;) { if (*s2 == '*') return TRUE; if (!*s1) { if (!*s2) return TRUE; break; } if (!*s2) { if (!*s1) return TRUE; break; } if (toupper(*s1++) != toupper(*s2++)) break; } return FALSE; } TDeviceEject::TDeviceEjectErrorCode TDeviceEject::EnumDevices(PEnumDeviceInfo ParentEnumDeviceInfo,PDWORD EjectDeviceFound,PCHAR EjectDevSpec,BOOL EjectDevSpecIsName,DEVINST DevInst,int Indent,PDWORD NativeErrorCode) { TDeviceEjectErrorCode Result = deec_Ok; DEVINST ThisDevInst = DevInst; while (Result == deec_Ok) { ULONG Status; // DN_... ULONG ProblemNumber; CONFIGRET r = Func_GetDevNodeStatus(&Status,&ProblemNumber,ThisDevInst,0); if (r == CR_NO_SUCH_DEVNODE) { } else if (r != CR_SUCCESS) { Result = deec_ErrorGettingDevNodeStatus; *NativeErrorCode = r; } if (Result == deec_Ok) { ULONG DeviceIDLen; r = Func_GetDeviceIDSize(&DeviceIDLen,ThisDevInst,0); if (r != CR_SUCCESS) { Result = deec_ErrorGettingDeviceIdSize; *NativeErrorCode = r; } else { PCHAR DeviceID = new CHAR[DeviceIDLen + 1]; if (DeviceID) { r = Func_GetDeviceID(ThisDevInst,DeviceID,DeviceIDLen + 1,0); if (r != CR_SUCCESS) { Result = deec_ErrorGettingDeviceId; *NativeErrorCode = r; } else { CHAR FriendlyName[512]; if (!GetFriendlyName(DeviceID,FriendlyName,sizeof FriendlyName)) FriendlyName[0] = ''; if (Verbose) { for (int i = 0;i < Indent * 2;++i) printf(" "); printf("%s",DeviceID); if (Debug) { printf(" DevInst: %u",ThisDevInst); printf(" Status: 0x%X ",Status); } if (FriendlyName[0]) printf(" '%s'",FriendlyName); if (Status & DN_REMOVABLE) printf(" [REMOVEABLE]"); if (ProblemNumber) printf(" ProblemNumber: %u",ProblemNumber); printf("\n"); } else { if (!EjectDevSpec || !EjectDevSpec[0]) if (Status & DN_REMOVABLE) { if (FriendlyName[0]) printf("'%s' ",FriendlyName); printf("'%s' [REMOVEABLE]\n",DeviceID); } } BOOL Found = FALSE; if (EjectDevSpec && EjectDevSpec[0]) { if (EjectDevSpecIsName) { if (FriendlyName[0]) Found = CompareWithWildcard(FriendlyName,EjectDevSpec); } else Found = CompareWithWildcard(DeviceID,EjectDevSpec); } if (Found) { ++*EjectDeviceFound; DEVINST EjectDevInst = ThisDevInst; if (!(Status & DN_REMOVABLE)) { // Dieses Device ist nicht auswerfbar, probiere übergeordneten Eintrag for (PEnumDeviceInfo EDI = ParentEnumDeviceInfo;EDI;EDI = EDI->Parent) { if (EDI->Status & DN_REMOVABLE) { EjectDevInst = EDI->DevInst; Status = EDI->Status; ProblemNumber = EDI->ProblemNumber; break; } } } if (!(Status & DN_REMOVABLE)) { Result = deec_DeviceNotRemovable; printf("Device"); if (FriendlyName[0]) printf(" '%s'",FriendlyName); printf(" [%s] not removable!\n",DeviceID); } else { if (ProblemNumber) { Result = deec_DeviceHasProblem; *NativeErrorCode = ProblemNumber; } else { printf("Ejecting "); if (FriendlyName[0]) printf(" '%s'",FriendlyName); printf(" [%s]...",DeviceID); PNP_VETO_TYPE VetoType; CHAR VetoName[MAX_PATH]; r = Func_RequestDeviceEject(EjectDevInst,&VetoType,VetoName,sizeof VetoName,0); if (r == CR_SUCCESS) printf("ok.\n"); else { printf("FAILED (%u,%u)\n",r,VetoType); if (r == CR_REMOVE_VETOED) { Result = deec_ErrorEjectVetoed; *NativeErrorCode = VetoType; } else { Result = deec_ErrorDeviceEject; *NativeErrorCode = r; } } } } } } delete [] DeviceID; } } } if (Result == deec_Ok) { DEVINST Child; r = Func_GetChild(&Child,ThisDevInst,0); if (r == CR_NO_SUCH_DEVNODE) { } else if (r != CR_SUCCESS) { Result = deec_ErrorGettingChild; *NativeErrorCode = r; } else { TEnumDeviceInfo EnumDeviceInfo; EnumDeviceInfo.Parent = ParentEnumDeviceInfo; EnumDeviceInfo.DevInst = ThisDevInst; EnumDeviceInfo.Status = Status; EnumDeviceInfo.ProblemNumber = ProblemNumber; Result = EnumDevices(&EnumDeviceInfo,EjectDeviceFound,EjectDevSpec,EjectDevSpecIsName,Child,Indent + 1,NativeErrorCode); } if (Result == deec_Ok) { DEVINST Sibling; r = Func_GetSibling(&Sibling,ThisDevInst,0); if (r == CR_NO_SUCH_DEVNODE) break; if (r != CR_SUCCESS) { Result = deec_ErrorGettingSibling; *NativeErrorCode = r; } ThisDevInst = Sibling; } } } return Result; } TDeviceEject::TDeviceEjectErrorCode TDeviceEject::Eject(PCHAR EjectDevSpec,BOOL EjectDevSpecIsName,PDWORD NativeErrorCode,PDWORD EjectedCount) { TDeviceEjectErrorCode Result = deec_Ok; *NativeErrorCode = 0; if (EjectedCount) *EjectedCount = 0; if (!Func_LocateDevNode || !Func_GetChild || !Func_GetSibling || !Func_GetDevNodeStatus || !Func_GetDeviceIDSize || !Func_GetDeviceID || !Func_RequestDeviceEject) Result = deec_LibraryFunctionMissing; else { DEVINST RootDevInst; CONFIGRET r = Func_LocateDevNode(&RootDevInst,NULL,0/*CM_LOCATE_DEVNODE_NORMAL*/); if (r != CR_SUCCESS) { Result = deec_ErrorLocatingDevNode; *NativeErrorCode = r; } else { DWORD EjectDeviceFound = 0; Result = EnumDevices(NULL,&EjectDeviceFound,EjectDevSpec,EjectDevSpecIsName,RootDevInst,0,NativeErrorCode); if ((Result == deec_Ok) && EjectDevSpec[0] && !EjectDeviceFound) Result = deec_DeviceNotFound; if (EjectedCount) *EjectedCount = EjectDeviceFound; } } return Result; } int main(int argc,char *argv[]) { int ExitCode = 0; printf("DevEject 1.0 2003 c't/Matthias Withopf\n\n"); BOOL ArgsOk = TRUE; BOOL Verbose = FALSE; BOOL Debug = FALSE; CHAR EjectDrive[80]; CHAR EjectDevSpec[1024]; EjectDrive[0] = ''; EjectDevSpec[0] = ''; BOOL EjectDevSpecIsName = FALSE; for (int i = 1;i < argc;++i) { if (!strcmp(argv[i],"-v")) Verbose = TRUE; else if (!strcmp(argv[i],"-Debug")) Debug = TRUE; else if (!strncmp(argv[i],"-EjectDrive:",12)) { strncpy(EjectDrive,argv[i] + 12,sizeof EjectDrive - 1); EjectDrive[sizeof EjectDrive - 1] = ''; if (!TDeviceEject::GetDriveDeviceId(EjectDrive,EjectDevSpec,sizeof EjectDevSpec)) { printf("Invalid drive specification '%s'!\n",EjectDrive); ArgsOk = FALSE; break; } EjectDevSpecIsName = FALSE; } else if (!strncmp(argv[i],"-EjectName:",11)) { strncpy(EjectDevSpec,argv[i] + 11,sizeof EjectDevSpec - 1); EjectDevSpec[sizeof EjectDevSpec - 1] = ''; EjectDevSpecIsName = TRUE; } else if (!strncmp(argv[i],"-EjectId:",9)) { strncpy(EjectDevSpec,argv[i] + 9,sizeof EjectDevSpec - 1); EjectDevSpec[sizeof EjectDevSpec - 1] = ''; EjectDevSpecIsName = FALSE; } else { printf("Unknown argument '%s'!\n",argv[i]); ArgsOk = FALSE; break; } } if (!ArgsOk) { ExitCode = 10; printf("Usage: %s -EjectDrive:<Drive>|-EjectName:<Name>|-EjectId:<DeviceId> [-v] [-Debug]\n",argv[0]); } else { if (Verbose) { if (EjectDrive[0]) printf("Ejecting: %s -> %s\n",EjectDrive,EjectDevSpec); else if (EjectDevSpec[0]) printf("Ejecting: %s\n",EjectDevSpec); } PDeviceEject DeviceEject = new TDeviceEject(Verbose,Debug); if (!DeviceEject) ExitCode = 11; else { if (DeviceEject->DeviceEjectErrorCode) { ExitCode = 12; switch(DeviceEject->DeviceEjectErrorCode) { case TDeviceEject::deec_UnsupportedOS: printf("Operating system not supported!\n"); break; default: printf("Error in device eject, error code %u,%u!\n",DeviceEject->DeviceEjectErrorCode,DeviceEject->NativeErrorCode); break; } } else { DWORD NativeErrorCode; DWORD EjectedCount; TDeviceEject::TDeviceEjectErrorCode ErrorCode = DeviceEject->Eject(EjectDevSpec,EjectDevSpecIsName,&NativeErrorCode,&EjectedCount); if (ErrorCode == TDeviceEject::deec_Ok) { if (EjectDevSpec[0]) printf("%u device(s) ejected.\n",EjectedCount); } else { ExitCode = 13; switch(ErrorCode) { case TDeviceEject::deec_DeviceNotFound: printf("Error ejecting device %s, not found (%u,%u)!\n",EjectDevSpec,ErrorCode,NativeErrorCode); break; case TDeviceEject::deec_DeviceNotRemovable: printf("Error ejecting device %s, not removable (%u,%u)!\n",EjectDevSpec,ErrorCode,NativeErrorCode); break; case TDeviceEject::deec_DeviceHasProblem: printf("Error ejecting device %s, has problem (%u,%u)!\n",EjectDevSpec,ErrorCode,NativeErrorCode); break; case TDeviceEject::deec_ErrorEjectVetoed: printf("Error ejecting device %s, vetoed (%u,%u)!\n",EjectDevSpec,ErrorCode,NativeErrorCode); break; default: printf("Error ejecting device %s, error code %u,%u!\n",EjectDevSpec,ErrorCode,NativeErrorCode); break; } } } delete DeviceEject; } } return ExitCode; } bye bye Edited June 29, 2007 by icemax Link to comment Share on other sites More sharing options...
Uten Posted June 29, 2007 Share Posted June 29, 2007 Modify this to fit your needs. rundll32.exe shell32.dll,Control_RunDLL hotplug.dll Please keep your sig. small! Use the help file. Search the forum. Then ask unresolved questions :) Script plugin demo, Simple Trace udf, TrayMenuEx udf, IOChatter demo, freebasic multithreaded dll sample, PostMessage, Aspell, Code profiling Link to comment Share on other sites More sharing options...
Uten Posted June 29, 2007 Share Posted June 29, 2007 Someone just posted something in scripts to.. Please keep your sig. small! Use the help file. Search the forum. Then ask unresolved questions :) Script plugin demo, Simple Trace udf, TrayMenuEx udf, IOChatter demo, freebasic multithreaded dll sample, PostMessage, Aspell, Code profiling Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now