i seems to get another DLLCALL Problem again ...
---
i do use
- Code: Select all Expand view RUN
- DLLCALL( "Kernel32.dll", ...
but Result is 0 ...
as it look like the same Problem which i had with "Everything" i guess i need other Way under Fivewin
- Code: Select all Expand view RUN
- hDll = LoadLibrary( "Kernel32.dll" )
so i "load" DLL once at Start and than use hDll Handle.
this work fine with "Everything" ... but i´m NOT allowed to "unload" as it fail when "load" again ... hm
so i like to ask if here is another Way to use DLL under Fivewin or what i´m doing wrong
---
Sample is to "safe remove" USE-Stick but it fail with
Error : can not LockVolume() 0
i guess CreateVolHandle() does not work correct under Fivewin
btw. i use UTF-8 or ANSI Function depend on hb_cdpSelect()
what does Fivewin need
- Code: Select all Expand view RUN
- #include "FIVEWIN.ch"
#include "common.ch"
#include "EJECTDLL.CH"
#include "dll.ch"
#define DLL_CDECL 0x08
#define DLL_STDCALL 0x20
#define DLL_SYSTEM 0x04
#if defined( __PLATFORM__WINDOWS )
#define DLL_OSAPI DLL_STDCALL
#elif defined( __PLATFORM__OS2 )
#define DLL_OSAPI DLL_SYSTEM
#else
#define DLL_OSAPI DLL_CDECL
#endif
#define FILE_SHARE_READ 0x00000001
#define FILE_SHARE_WRITE 0x00000002
#define FILE_SHARE_DELETE 0x00000004
#define FILE_SHARE_VALID_FLAGS 0x00000007
#define GENERIC_READ 0x80000000
#define GENERIC_WRITE 0x40000000
#define GENERIC_EXECUTE 0x20000000
#define GENERIC_ALL 0x10000000
#define OPEN_EXISTING 3
#define DRIVE_UNKNOWN 0
#define DRIVE_NO_ROOT_DIR 1
#define DRIVE_REMOVABLE 2
#define DRIVE_FIXED 3
#define DRIVE_REMOTE 4
#define DRIVE_CDROM 5
#define DRIVE_RAMDISK 6
#define SW_SHOW 5
STATIC caItems := {} // for GRID
STATIC acImage := {}
STATIC cInfo := ""
STATIC aDrives
STATIC hDLL
MEMVAR oFontDefault
MEMVAR BFcolor, BGcolor
*+--------------------------------------------------------------------
*+
*+ Procedure USBeject()
*+
*+ Called from ( dualgrid.prg ) 1 - static procedure buildmainmenu()
*+
*+--------------------------------------------------------------------
*+
PROCEDURE USBeject()
LOCAL oDlg, oListbox
LOCAL cDrive := SPACE( 2 )
LOCAL cTitle := "Please, select"
LOCAL aDrives := FillDriveArray()
// Codeblock not filled yet
LOCAL bSetGet
LOCAL bChange
LOCAL bValid
LOCAL bLDblClicked
LOCAL bWhen
LOCAL bDrawItem
DEFINE DIALOG oDlg FROM 5, 10 TO 24, 55 TITLE cTitle COLOR BFcolor, BGcolor
@ 1, 2 LISTBOX oListbox VAR cDrive ITEMS aDrives[1] SIZE 145, 95 PIXEL FONT oFontDefault COLOR BFcolor, BGcolor OF oDlg
* oListbox := TListBox() :New( 10, 20, bSetGet, aDrives[ 1 ], 145, 95, bChange, ;
* oDlg, bValid, BFcolor, BGcolor, .T., .F., ;
* bLDblClicked, oFontDefault, "", .T., bWhen, aDrives[ 2 ], ;
* bDrawItem, .F., .F. )
oListbox:SetItems( aDrives[ 1 ], .T. )
oListbox:SetBitmaps( aDrives[ 2 ] )
IF !EMPTY( aDrives[ 3 ] )
oListbox:Select( aDrives[ 3 ] )
ENDIF
@ 7, 7 BUTTON "&OK" OF oDlg SIZE 40, 12 ;
ACTION( EjectMedia( cDrive ), oDlg:End() ) DEFAULT
@ 7, 17 BUTTON "&Cancel" OF oDlg SIZE 40, 12 ;
ACTION( cDrive := nil, oDlg:End() )
#IFDEF __HMG__
END DIALOG
#ENDIF
ACTIVATE DIALOG oDlg CENTERED
RETURN
*+--------------------------------------------------------------------
*+
*+ Function EjectMedia()
*+
*+ Called from ( hbeject.prg ) 1 - procedure usbeject()
*+
*+--------------------------------------------------------------------
*+
FUNCTION EjectMedia( cDrive, UseCDdrives )
// ***************************************************************
//
// USBeject based on https://support.microsoft.com/en-us/kb/165721
//
// will eject CD / DVD and "flush Buffer" if USB Drive
//
// ***************************************************************
LOCAL hVolRead := - 1 // "CreateFileA"
LOCAL nLock := 0 // "DeviceIoControl",hVolRead, FSCTL_LOCK_VOLUME
LOCAL nDisMount := 0 // "DeviceIoControl",hVolRead, FSCTL_DISMOUNT_VOLUME
LOCAL nEject := 0 // "DeviceIoControl",hVolRead, IOCTL_STORAGE_EJECT_MEDIA
LOCAL nAccess := 0
LOCAL nType := 0
LOCAL cMsg := ""
LOCAL nRemove := 0
LOCAL lRet := .T.
LOCAL cAction := GETENV( "SYSTEMROOT" ) + "\SYSTEM32\HOTPLUG.DLL"
LOCAL cRoot := "RUNDLL32.EXE "
LOCAL cPath := GETENV( "TEMP" ) + "\"
DEFAULT UseCDdrives TO .F.
IF PCOUNT() = 0
MsgInfo( "need Drive Letter" )
RETURN .F.
ENDIF
IF EMPTY( cDrive )
MsgInfo( "Error no Drive Letter" )
RETURN .F.
ELSE
cDrive := SUBSTR( cDrive, 1, 1 )
ENDIF
cAction += ",HotPlugSafeRemovalDriveNotification "
cAction += VOLUMENAME( cDrive + ":\" )
cAction += " ("
cAction += cDrive + ":)"
msginfo(cDrive)
nType := DriveType( cDrive )
DO CASE
CASE nType = DRIVE_UNKNOWN
CASE nType = DRIVE_NO_ROOT_DIR
CASE nType = DRIVE_REMOVABLE // Floppy
nAccess := GENERIC_READ + GENERIC_WRITE
CASE nType = DRIVE_FIXED
CASE nType = DRIVE_REMOTE
CASE nType = DRIVE_CDROM
IF UseCDdrives = .T.
nAccess := GENERIC_READ
ENDIF
CASE nType = DRIVE_RAMDISK
OTHERWISE
MsgInfo( "can not use Type " + STR( nType ) )
ENDCASE
IF EMPTY( nAccess )
RETURN .F.
ENDIF
cInfo := "" // reset STATIC for SayInfo()
SayInfo( "waiting for Drive " + cDrive + CRLF )
hVolRead := CreateVolHandle( @cMsg, nType, nAccess, cDrive )
IF hVolRead = - 1
MsgInfo( "Unable to open drive " + cDrive )
lRet := .F.
ELSE
// *********************************************************
//
// https://msdn.microsoft.com/en-us/library/Aa363216.aspx
//
// BOOL WINAPI DeviceIoControl(
// _In_ HANDLE hDevice,
// _In_ DWORD dwIoControlCode,
// _In_opt_ LPVOID lpInBuffer,
// _In_ DWORD nInBufferSize,
// _Out_opt_ LPVOID lpOutBuffer,
// _In_ DWORD nOutBufferSize,
// _Out_opt_ LPDWORD lpBytesReturned,
// _Inout_opt_ LPOVERLAPPED lpOverlapped
// );
//
// *********************************************************
nLock := LockVolume( hVolRead )
IF nLock <> 0
cMsg := "LockVolume()" + CRLF
SayInfo( cMsg )
nDisMount := DismountVolume( hVolRead )
IF nDisMount <> 0
cMsg := "DismountVolume()" + CRLF
SayInfo( cMsg )
// nRemove := PreventRemovalOfVolume( hVolRead, .F. )
nRemove := 1
IF nRemove <> 0
cMsg := "PreventRemovalOfVolume()" + CRLF
SayInfo( cMsg )
nEject := AutoEjectVolume( hVolRead )
// IF nEject = 0
cMsg := "AutoEjectVolume()" + CRLF
SayInfo( cMsg )
// ELSE
// cMsg := "Error : can not AutoEjectVolume() "+VAR2CHAR(nEject))
// lRet := .F.
// ENDIF
ELSE
cMsg := "Error : can not PreventRemovalOfVolume() " + VAR2CHAR( nRemove )
lRet := .F.
SayInfo( cMsg )
ENDIF
ELSE
cMsg := "Error : can not DismountVolume() " + VAR2CHAR( nDisMount )
lRet := .F.
SayInfo( cMsg )
ENDIF
ELSE
cMsg := "Error : can not LockVolume() " + VAR2CHAR( nLock )
lRet := .F.
SayInfo( cMsg )
ENDIF
ENDIF
CloseVolume( hVolRead )
IF lRet = .F.
Msginfo( cMsg )
ELSE
SayInfo( "remove your USE-Stick now" )
hb_IdleSleep( 2.0 )
IF nType <> DRIVE_CDROM // will eject
MEMOWRIT( cPath + "ShowMsg.BAT", cRoot + cAction )
ShellExecute( 0, "runas", cPath + "ShowMsg.BAT",,, SW_SHOW )
hb_IdleSleep( 2.0 )
FERASE( cPath + "ShowMsg.BAT" )
ENDIF
ENDIF
RETURN lRet
*+--------------------------------------------------------------------
*+
*+ Static Function CreateVolHandle()
*+
*+ Called from ( hbeject.prg ) 1 - function ejectmedia()
*+
*+--------------------------------------------------------------------
*+
STATIC FUNCTION CreateVolHandle( cMsg, nType, nAccess, cDrive )
LOCAL hVolWrite
LOCAL hVolRead
LOCAL nFlush := 0 // "FlushFileBuffers"
LOCAL cPath := ""
LOCAL nShare := FILE_SHARE_READ + FILE_SHARE_WRITE
LOCAL nDispo := OPEN_EXISTING
LOCAL nAttrib := 0 // FILE_FLAG_OVERLAPPED + FILE_FLAG_BACKUP_SEMANTICS
/**********************************************************
*
* https://msdn.microsoft.com/en-us/library/aa363858.aspx
*
* HANDLE WINAPI CreateFile(
* _In_ LPCTSTR lpFileName,
* _In_ DWORD dwDesiredAccess,
* _In_ DWORD dwShareMode,
* _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
* _In_ DWORD dwCreationDisposition,
* _In_ DWORD dwFlagsAndAttributes,
* _In_opt_ HANDLE hTemplateFile
* );
*
**********************************************************/
cPath := "\\.\"
cPath += cDrive
cPath += ":"
// Kernel32
IF hb_cdpSelect() = "UTF8"
hVolWrite := DLLCALL( "Kernel32.dll", DLL_OSAPI, "CreateFileW", cPath, ; // lpFileName
nAccess, ; // dwDesiredAccess
nShare, ; // dwShareMode
NULL, ; // lpSecurityAttributes
nDispo, ; // dwCreationDisposition
nAttrib, ; // dwFlagsAndAttributes
NULL ) // hTemplateFile
ELSE
hVolWrite := DLLCALL( "Kernel32.dll", DLL_OSAPI, "CreateFile", cPath, ; // lpFileName
nAccess, ; // dwDesiredAccess
nShare, ; // dwShareMode
NULL, ; // lpSecurityAttributes
nDispo, ; // dwCreationDisposition
nAttrib, ; // dwFlagsAndAttributes
NULL ) // hTemplateFile
ENDIF
IF hVolWrite = - 1
RETURN hVolWrite
ELSE
// flush buffer
//
IF nType <> DRIVE_CDROM
// Kernel32
nFlush := DLLCALL( "Kernel32.dll", DLL_OSAPI, "FlushFileBuffers", hVolWrite )
cMsg := "FlushFile()" + CRLF
ENDIF
ENDIF
// Kernel32
DLLCALL( "Kernel32.dll", DLL_OSAPI, "CloseHandle", hVolWrite )
// open again RO
//
nAccess := GENERIC_READ
// Kernel32
IF hb_cdpSelect() = "UTF8"
hVolRead := DLLCALL( "Kernel32.dll", DLL_OSAPI, "CreateFileW", cPath, ; // lpFileName
nAccess, ; // dwDesiredAccess
nShare, ; // dwShareMode
NULL, ; // lpSecurityAttributes
nDispo, ; // dwCreationDisposition
nAttrib, ; // dwFlagsAndAttributes
NULL ) // hTemplateFile
ELSE
hVolRead := DLLCALL( "Kernel32.dll", DLL_OSAPI, "CreateFile", cPath, ; // lpFileName
nAccess, ; // dwDesiredAccess
nShare, ; // dwShareMode
NULL, ; // lpSecurityAttributes
nDispo, ; // dwCreationDisposition
nAttrib, ; // dwFlagsAndAttributes
NULL ) // hTemplateFile
ENDIF
RETURN hVolRead
*+--------------------------------------------------------------------
*+
*+ Static Function LockVolume()
*+
*+ Called from ( hbeject.prg ) 1 - function ejectmedia()
*+
*+--------------------------------------------------------------------
*+
STATIC FUNCTION LockVolume( hVolRead )
LOCAL nBytes := 0
LOCAL nLock
// Kernel32
nLock := DLLCALL( "Kernel32.dll", DLL_OSAPI, "DeviceIoControl", hVolRead, ;
FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, @nBytes, NULL )
RETURN nLock
*+--------------------------------------------------------------------
*+
*+ Static Function DismountVolume()
*+
*+ Called from ( hbeject.prg ) 1 - function ejectmedia()
*+
*+--------------------------------------------------------------------
*+
STATIC FUNCTION DismountVolume( hVolRead )
LOCAL nBytes := 0
LOCAL nDisMount
// Kernel32
nDisMount := DLLCALL( "Kernel32.dll", DLL_OSAPI, "DeviceIoControl", hVolRead, ;
FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0, @nBytes, NULL )
RETURN nDisMount
*+--------------------------------------------------------------------
*+
*+ Static Function AutoEjectVolume()
*+
*+ Called from ( hbeject.prg ) 1 - function ejectmedia()
*+
*+--------------------------------------------------------------------
*+
STATIC FUNCTION AutoEjectVolume( hVolRead )
LOCAL nBytes := 0
LOCAL nEject
// Kernel32
nEject := DLLCALL( "Kernel32.dll", DLL_OSAPI, "DeviceIoControl", hVolRead, ;
IOCTL_STORAGE_EJECT_MEDIA, NULL, 0, NULL, 0, @nBytes, NULL )
RETURN nEject
*+--------------------------------------------------------------------
*+
*+ Static Function UnlockVolume()
*+
*+--------------------------------------------------------------------
*+
STATIC FUNCTION UnlockVolume( hVolRead )
LOCAL nBytes := 0
LOCAL nUnlock
// Kernel32
nUnlock := DLLCALL( "Kernel32.dll", DLL_OSAPI, "DeviceIoControl", hVolRead, ;
FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, @nBytes, NULL )
RETURN nUnlock
*+--------------------------------------------------------------------
*+
*+ Static Function CloseVolume()
*+
*+ Called from ( hbeject.prg ) 1 - function ejectmedia()
*+
*+--------------------------------------------------------------------
*+
STATIC FUNCTION CloseVolume( hVolRead )
LOCAL lClose
// Kernel32
IF hb_cdpSelect() = "UTF8"
lClose := DLLCALL( "Kernel32.dll", DLL_OSAPI, "CloseHandleW", hVolRead )
ELSE
lClose := DLLCALL( "Kernel32.dll", DLL_OSAPI, "CloseHandleA", hVolRead )
ENDIF
RETURN lClose
*+--------------------------------------------------------------------
*+
*+ Static Function PreventRemovalOfVolume()
*+
*+--------------------------------------------------------------------
*+
STATIC FUNCTION PreventRemovalOfVolume( hVolRead, fPreventRemoval )
LOCAL nBytes := 0
LOCAL nRemove
LOCAL pmr := 1 // PREVENT_MEDIA_REMOVAL():New()
LOCAL nSize := pmr:_sizeof_()
pmr:PreventMediaRemoval := fPreventRemoval
nSize := 1
// Kernel32
nRemove := DLLCALL( "Kernel32.dll", DLL_OSAPI, "DeviceIoControl", hVolRead, ;
IOCTL_STORAGE_MEDIA_REMOVAL, @pmr, nSize, NULL, 0, @nBytes, NULL )
RETURN nRemove
*+--------------------------------------------------------------------
*+
*+ Procedure SayInfo()
*+
*+ Called from ( hbeject.prg ) 9 - function ejectmedia()
*+
*+--------------------------------------------------------------------
*+
PROCEDURE SayInfo( cText )
RETURN
*+ EOF: HBEJECT.PRG
"EJECTDLL.CH"
- Code: Select all Expand view RUN
- #define VERSION_XP 5.0
#define VERSION_VISTA 6.0
#define VERSION_WIN7 6.01
#define VERSION_WIN8 6.02
#define VERSION_WIN81 6.03
#define VERSION_WIN10 10.0
#define VERSION_WIN10OLD 6.04
#define NULL 0
#define MAX_PATH 200
#define MIN_PATH 10
#define FORMAT_MESSAGE_FROM_SYSTEM 0x00001000
#define GUID_DEVINTERFACE_VOLUME "{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}"
#define GUID_DEVINTERFACE_DISK "{53f56307-b6bf-11d0-94f2-00a0c91efb8b}"
#define GUID_DEVINTERFACE_FLOPPY "{53f56311-b6bf-11d0-94f2-00a0c91efb8b}"
#define GUID_DEVINTERFACE_CDROM "{53f56308-b6bf-11d0-94f2-00a0c91efb8b}"
#define GUID_DEVINTERFACE_USB_DEVICE "{A5DCBF10-6530-11D2-901F-00C04FB951ED}"
//
// Configuration Manager CONFIGRET return status codes
//
#define CR_SUCCESS (0x00000000)
#define CR_DEFAULT (0x00000001)
#define CR_OUT_OF_MEMORY (0x00000002)
//
// Flags for CM_Query_And_Remove_SubTree
//
#define CM_REMOVE_UI_OK 0x00000000
#define CM_REMOVE_UI_NOT_OK 0x00000001
#define CM_REMOVE_NO_RESTART 0x00000002
#define CM_REMOVE_BITS 0x00000003
// Flags controlling what is included in the device information set built
// by SetupDiGetClassDevs
//
#define DIGCF_DEFAULT 0x00000001 // only valid with DIGCF_DEVICEINTERFACE
#define DIGCF_PRESENT 0x00000002
#define DIGCF_ALLCLASSES 0x00000004
#define DIGCF_PROFILE 0x00000008
#define DIGCF_DEVICEINTERFACE 0x00000010
//
// Flags for SP_DEVICE_INTERFACE_DATA.Flags field.
//
#define SPINT_ACTIVE 0x00000001
#define SPINT_DEFAULT 0x00000002
#define SPINT_REMOVED 0x00000004
#define METHOD_BUFFERED 0
#define METHOD_IN_DIRECT 1
#define METHOD_OUT_DIRECT 2
#define METHOD_NEITHER 3
#define FILE_ANY_ACCESS 0
#define FILE_SPECIAL_ACCESS (FILE_ANY_ACCESS)
#define FILE_READ_ACCESS ( 0x0001 ) // file & pipe
#define FILE_WRITE_ACCESS ( 0x0002 ) // file & pipe
#define FILE_DEVICE_MASS_STORAGE 0x0000002d
#define IOCTL_STORAGE_BASE FILE_DEVICE_MASS_STORAGE
#xtranslate CTL_CODE( <dt> , <fn> , <mtd> , <acc> ) =>;
nOr( nLShift(<dt>,16) , nLShift(<acc>,14) , nLShift(<fn>,2) , <mtd> )
#define IOCTL_STORAGE_GET_DEVICE_NUMBER CTL_CODE(IOCTL_STORAGE_BASE, 0x0420, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define FILE_FLAG_BACKUP_SEMANTICS 0x02000000
#define FILE_FLAG_OVERLAPPED 0x40000000
#define FSCTL_LOCK_VOLUME 0x00090018
#define FSCTL_UNLOCK_VOLUME 0x0009001C
#define FSCTL_DISMOUNT_VOLUME 0x00090020
#define IOCTL_STORAGE_EJECT_MEDIA 0x002D4808 // IOCTL_DISK_EJECT_MEDIA
#define IOCTL_STORAGE_MEDIA_REMOVAL 0x002D4804
#define SE_ERR_FNF 2 // File not found.
#define SE_ERR_PNF 3 // Path not found.
#define SE_ERR_ACCESSDENIED 5 // Access denied.
#define SE_ERR_OOM 8 // Out of memory.
#define SE_ERR_SHARE 26 // Cannot share an open file.
#define SE_ERR_ASSOCINCOMPLETE 27 // File association information not complete.
#define SE_ERR_DDETIMEOUT 28 // DDE operation timed out.
#define SE_ERR_DDEFAIL 29 // DDE operation failed.
#define SE_ERR_DDEBUSY 30 // DDE operation is busy.
#define SE_ERR_NOASSOC 31 // File association not available.
#define SE_ERR_DLLNOTFOUND 32 // Dynamic-link library not found.