#include "FIVEWIN.ch"
#include "common.ch"
#include "dll.ch"
#include "hbdyn.ch"
#include "EJECTDLL.CH"
#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
#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
MEMVAR hDLL
*+--------------------------------------------------------------------
*+
*+ 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 := aDrives()
LOCAL bSetGet := {|x| cDrive := x }
LOCAL bChange
LOCAL bValid
LOCAL bLDblClicked
LOCAL bWhen
LOCAL bDrawItem
PRIVATE hDLL
DEFINE DIALOG oDlg FROM 5, 10 TO 24, 55 TITLE cTitle
oListbox := TListBox() :New( 10, 20, bSetGet, aDrives, 145, 95, bChange, ;
oDlg, bValid, , , .T., .F., ;
bLDblClicked, , "", .T., bWhen,, ;
bDrawItem, .F., .F. )
@ 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
IF EMPTY(hDll)
hDll := LoadLibrary( "Kernel32.dll" )
ENDIF
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() "+hb_valToExp(nEject))
// lRet := .F.
// ENDIF
ELSE
cMsg := "Error : can not PreventRemovalOfVolume() " + hb_valToExp( nRemove )
lRet := .F.
SayInfo( cMsg )
ENDIF
ELSE
cMsg := "Error : can not DismountVolume() " + hb_valToExp( nDisMount )
lRet := .F.
SayInfo( cMsg )
ENDIF
ELSE
cMsg := "Error : can not LockVolume() " + hb_valToExp( 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
FWLOG "CreateVolHandle"
/**********************************************************
*
* 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 += ":"
hVolWrite := CreateFile( cPath , ; // lpFileName
nAccess, ; // dwDesiredAccess
nShare , ; // dwShareMode
NULL , ; // lpSecurityAttributes
nDispo , ; // dwCreationDisposition
nAttrib, ; // dwFlagsAndAttributes
NULL ) // hTemplateFile
IF hVolWrite = - 1
msginfo("Error hVolWrite = - 1 ")
RETURN hVolWrite
ELSE
// flush buffer
//
IF nType <> DRIVE_CDROM
// Kernel32
nFlush := FlushFileBuffers( hVolWrite )
cMsg := "FlushFile()" + CRLF
ENDIF
ENDIF
CloseHandle(hVolWrite )
// open again RO
//
nAccess := GENERIC_READ
hVolRead := CreateFile( cPath , ; // lpFileName
nAccess, ; // dwDesiredAccess
nShare , ; // dwShareMode
NULL , ; // lpSecurityAttributes
nDispo , ; // dwCreationDisposition
nAttrib, ; // dwFlagsAndAttributes
NULL ) // hTemplateFile
RETURN hVolRead
*+--------------------------------------------------------------------
*+
*+ Static Function LockVolume()
*+
*+ Called from ( hbeject.prg ) 1 - function ejectmedia()
*+
*+--------------------------------------------------------------------
*+
STATIC FUNCTION LockVolume( hVolRead )
LOCAL nBytes := 0
LOCAL nLock
nLock := 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
nDisMount := 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
nEject := 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
nUnlock := 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
lClose := CloseHandle( hVolRead )
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
nRemove := 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
* https://learn.microsoft.com/en-us/windo ... reatefilea
DLL FUNCTION CreateFile(lpFileName AS LPSTR ,;
dwDesiredAccess AS DWORD ,;
dwShareMode AS DWORD ,;
lpSecurityAttributes AS LONG ,;
dwCreationDisposition AS DWORD ,;
dwFlagsAndAttributes AS DWORD ,;
hTemplateFile AS LONG ) AS LONG PASCAL FROM "CreateFileA" LIB hDll
* https://learn.microsoft.com/en-us/windo ... ilebuffers
DLL FUNCTION FlushFileBuffers(hVolWrite AS LONG) AS LONG PASCAL FROM "FlushFileBuffers" LIB hDll
* https://learn.microsoft.com/en-us/windo ... losehandle
DLL FUNCTION CloseHandle( hVolRead AS LONG) AS LONG PASCAL FROM "CloseHandleA" LIB hDll
* https://learn.microsoft.com/en-us/windo ... eiocontrol
DLL FUNCTION DeviceIoControl( hDevice AS LONG ,;
dwIoControlCode AS DWORD ,;
lpInBuffer AS VOID ,;
nInBufferSize AS DWORD,;
lpOutBuffer AS VOID ,;
nOutBufferSize AS DWORD,;
lpBytesReturned AS DWORD,; // LPDWORD
lpOverlapped AS LPOVERLAPPED ) AS LONG PASCAL FROM "DeviceIoControl" LIB hDll
*+ EOF: HBEJECT.PRG
Antonio Linares wrote:If it works with HMG then it means there is a #define in FWH that is clashing with a Harbour #define or maybe HMG defines it in a different way
Please review this example to see how easily a new define can replace a previous one, and Harbour does not warn you:
- Code: Select all Expand view RUN
#define TEST 123
#define TEST "Another"
function Main()
? TEST
return nil
Warning W0002 Redefinition or duplicate definition of #define TEST
#define TEST 123
#undef TEST
#define TEST "Another"
function Main()
? TEST
return nil
Antonio Linares wrote:I get "Error no Drive Letter" in all cases (I have inserted a USB pendrive)
what to test ? How ?
// EjectMediaByLetter.cpp by Uwe Sieber - http://www.uwe-sieber.de
//
// Simple demonstration how to flush, lock and dismount a volume and eject a media from a drive
//
// Works under W2K, XP, W2K3, Vista, Win7, Win8, not tested under Win9x
//
// Console application - expects the drive letter of the drive to eject as parameter
//
// you are free to use this code in your projects
//
#define WIN32_LEAN_AND_MEAN
#include <stdio.h>
#include <windows.h>
#include <winioctl.h>
// returned errorlevels, nice to have when writing documentation later :-)
enum {
ERRL_SUCCESS = 0,
ERRL_INVALID_PARAM,
ERRL_NO_VOLREAD,
ERRL_NO_LOCK,
ERRL_NO_EJECT
};
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
// we expect a single drive letter as param, e.g.
// ejectmediabyletter X
//-------------------------------------------------------------------------------
int main(int argc, char* argv[])
{
bool ForceEject = false; // dismount and ejecting even we got no lock
if ( argc != 2 ) {
return ERRL_INVALID_PARAM;
}
char DriveLetter = argv[1][0]; // grab the drive letter only
DriveLetter &= ~0x20; // make uppercase
if ( DriveLetter < 'A' || DriveLetter > 'Z' ) {
return ERRL_INVALID_PARAM;
}
char szRootPath[] = "X:\\"; // "X:\" -> for GetDriveType
szRootPath[0] = DriveLetter;
char szVolumeAccessPath[] = "\\\\.\\X:"; // "\\.\X:" -> to open the volume
szVolumeAccessPath[4] = DriveLetter;
int res;
DWORD dwRet;
DWORD dwDriveType = GetDriveType(szRootPath);
// if it is no CD drive then we try to flush the volume
if ( dwDriveType != DRIVE_CDROM ) {
// try to flush, write access required which only admins will get
HANDLE hVolWrite = CreateFile(szVolumeAccessPath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if ( hVolWrite != INVALID_HANDLE_VALUE ) {
printf("Flushing cache...");
res = FlushFileBuffers(hVolWrite);
if ( res ) {
printf(" OK\n");
} else {
printf(" failed err=%u\n", GetLastError());
}
CloseHandle(hVolWrite);
}
}
HANDLE hVolRead = CreateFile(szVolumeAccessPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if ( hVolRead == INVALID_HANDLE_VALUE ) {
printf("error %u opening the volume for read access -> abort\n", GetLastError());
return ERRL_NO_VOLREAD;
}
// allowing (unlocking) eject, usually for CD/DVD only, but does not hurt (and returns TRUE) for other drives
printf("Allowing eject...");
PREVENT_MEDIA_REMOVAL pmr = {0}; // pmr.PreventMediaRemoval = FALSE;
res = DeviceIoControl(hVolRead, IOCTL_STORAGE_MEDIA_REMOVAL, &pmr, sizeof(pmr), NULL, 0, &dwRet, NULL);
if ( res ) {
printf(" OK\n");
} else {
printf(" failed err=%u\n", GetLastError());
}
// try to lock the volume, seems to flush too, maybe even with read access...
printf("Locking volume...");
int Locked = DeviceIoControl(hVolRead, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &dwRet, NULL);
if ( Locked ) {
printf(" OK\n");
} else {
printf(" failed err=%u\n", GetLastError());
}
if ( !Locked && !ForceEject ) {
return ERRL_NO_LOCK;
}
// dismount the file system if either we got a lock or we want to force it
printf("Dismounting volume...");
res = DeviceIoControl(hVolRead, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0, &dwRet, NULL);
if ( res ) {
printf(" OK\n");
} else {
printf(" failed err=%u\n", GetLastError());
}
printf("Ejecting media...");
res = DeviceIoControl(hVolRead, IOCTL_STORAGE_EJECT_MEDIA, NULL, 0, NULL, 0, &dwRet, NULL);
if ( res ) {
printf(" OK\n");
} else {
printf(" failed err=%u\n", GetLastError());
}
if ( Locked ) {
DeviceIoControl(hVolRead, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &dwRet, NULL);
}
CloseHandle(hVolRead);
if ( res ) {
return ERRL_SUCCESS;
}
return ERRL_NO_EJECT;
}
//----------------------------------/main----------------------------------------
//-------------------------------------------------------------------------------
Enrico Maria Giordano wrote:You should work with warnings activated. The correct way is:
-w1 -es2
#include "FIVEWIN.ch"
#include "common.ch"
PROCEDURE MAIN()
LOCAL oDlg, oListbox
LOCAL cDrive := SPACE( 2 )
LOCAL cTitle := "Please, select"
LOCAL aDrives := aDrives()
LOCAL bSetGet := { | x | cDrive := x }
LOCAL bChange
LOCAL bValid
LOCAL bLDblClicked
LOCAL bWhen
LOCAL bDrawItem
DEFINE DIALOG oDlg FROM 5, 10 TO 24, 55 TITLE cTitle
oListbox := TListBox() :New( 10, 20, bSetGet, aDrives, 145, 95, bChange, ;
oDlg, bValid,,, .T., .F., ;
bLDblClicked,, "", .T., bWhen,, ;
bDrawItem, .F., .F. )
@ 7, 7 BUTTON "&OK" OF oDlg SIZE 40, 12 ;
ACTION( USBeject( 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
STATIC PROCEDURE USBeject(cDriveLetter )
IF EjectRemovable( cDriveLetter )
MsgInfo( "The Drive " + cDriveLetter + " Can be Safely Removed", "Atenttion ! , Remove USB Ok" )
ELSE
MsgInfo( "Failed to Safely Remove/Eject Drive " + cDriveLetter , "Atenttion ! , Failed Remove USB" )
ENDIF
RETURN
********************************************************************************
* http://www.hmgforum.com/viewtopic.php?f=5&t=4524&hilit=cDriveLetter&start=10
* Made By PeteWG ( Pete ) & gfilatov (Grigory)
********************************************************************************
#pragma begindump
#include <windows.h>
#include <winioctl.h>
#include <tchar.h>
#include <stdio.h>
// Prototypes
BOOL EjectVolume(TCHAR cDriveLetter);
HANDLE OpenVolume(TCHAR cDriveLetter);
BOOL LockVolume(HANDLE hVolume);
BOOL DismountVolume(HANDLE hVolume);
BOOL PreventRemovalOfVolume(HANDLE hVolume, BOOL fPrevent);
BOOL AutoEjectVolume(HANDLE hVolume);
BOOL CloseVolume(HANDLE hVolume);
LPTSTR szVolumeFormat = TEXT("\\\\.\\%c:");
LPTSTR szRootFormat = TEXT("%c:\\");
HANDLE OpenVolume(TCHAR cDriveLetter)
{
HANDLE hVolume;
UINT uDriveType;
TCHAR szVolumeName[8];
TCHAR szRootName[5];
DWORD dwAccessFlags;
wsprintf(szRootName, szRootFormat, cDriveLetter);
uDriveType = GetDriveType(szRootName);
switch(uDriveType)
{
case DRIVE_REMOVABLE:
dwAccessFlags = GENERIC_READ | GENERIC_WRITE;
break;
case DRIVE_CDROM:
dwAccessFlags = GENERIC_READ;
break;
default:
return INVALID_HANDLE_VALUE;
}
wsprintf(szVolumeName, szVolumeFormat, cDriveLetter);
hVolume = CreateFile( szVolumeName,
dwAccessFlags,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL );
return hVolume;
}
BOOL CloseVolume(HANDLE hVolume)
{
return CloseHandle(hVolume);
}
#define LOCK_TIMEOUT 10000 // 10 Seconds
#define LOCK_RETRIES 20
BOOL LockVolume( HANDLE hVolume )
{
DWORD dwBytesReturned;
DWORD dwSleepAmount;
int nTryCount;
dwSleepAmount = LOCK_TIMEOUT / LOCK_RETRIES;
for( nTryCount = 0; nTryCount < LOCK_RETRIES; nTryCount++ )
{
if( DeviceIoControl( hVolume, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0,
&dwBytesReturned, NULL ) )
return TRUE;
Sleep( dwSleepAmount );
}
return FALSE;
}
BOOL DismountVolume( HANDLE hVolume )
{
DWORD dwBytesReturned;
return DeviceIoControl( hVolume, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0,
&dwBytesReturned, NULL );
}
BOOL PreventRemovalOfVolume(HANDLE hVolume, BOOL fPreventRemoval)
{
DWORD dwBytesReturned;
PREVENT_MEDIA_REMOVAL PMRBuffer;
PMRBuffer.PreventMediaRemoval = fPreventRemoval;
return DeviceIoControl( hVolume, IOCTL_STORAGE_MEDIA_REMOVAL,
&PMRBuffer, sizeof(PREVENT_MEDIA_REMOVAL),
NULL, 0, &dwBytesReturned, NULL );
}
AutoEjectVolume( HANDLE hVolume )
{
DWORD dwBytesReturned;
return DeviceIoControl( hVolume, IOCTL_STORAGE_EJECT_MEDIA, NULL, 0, NULL, 0,
&dwBytesReturned,
NULL );
}
BOOL EjectVolume( TCHAR cDriveLetter )
{
HANDLE hVolume;
BOOL fRemoveSafely = FALSE;
BOOL fAutoEject = FALSE;
hVolume = OpenVolume(cDriveLetter);
if( hVolume == INVALID_HANDLE_VALUE )
return FALSE;
if( LockVolume(hVolume) && DismountVolume(hVolume) )
{
fRemoveSafely = TRUE;
if (PreventRemovalOfVolume(hVolume, FALSE) && AutoEjectVolume(hVolume))
fAutoEject = TRUE;
}
if( ! CloseVolume(hVolume) )
return FALSE;
return TRUE;
}
#include "hbapi.h"
#include "hbapifs.h"
HB_FUNC( EJECTREMOVABLE )
{
char * szDrive = hb_parc( 1 );
hb_retl( EjectVolume( *szDrive ) );
return;
}
#pragma enddump
*+ EOF: FWEJECT.PRG
Warning W8004 FWEJECT.prg 192: 'fAutoEject' is assigned a value that is never used in function EjectVolume
Warning W8004 FWEJECT.prg 192: 'fRemoveSafely' is assigned a value that is never used in function EjectVolume
Warning W8075 FWEJECT.prg 198: Suspicious pointer conversion in function HB_FUN_EJECTREMOVABLE
Jimmy wrote:how to fix there WarningsWarning W8004 FWEJECT.prg 192: 'fAutoEject' is assigned a value that is never used in function EjectVolume
Warning W8004 FWEJECT.prg 192: 'fRemoveSafely' is assigned a value that is never used in function EjectVolume
Warning W8075 FWEJECT.prg 198: Suspicious pointer conversion in function HB_FUN_EJECTREMOVABLE
BOOL fRemoveSafely; // = FALSE;
BOOL fAutoEject; // = FALSE;
hb_retl( EjectVolume( ( TCHAR ) *szDrive ) );
HB_FUNC( DISMOUNTVOLUME )
{
hb_retl( DismountVolume( hb_parnll( 1 ) ) );
}
HB_FUNC(EJECTVOLUME)
{
return EjectVolume(hb_parc(1));
}
HB_FUNC(OPENVOLUME)
{
return OpenVolume(hb_parc(1));
}
HB_FUNC(LOCKVOLUME)
{
return LockVolume(hb_parnl(1));
}
HB_FUNC(DISMOUNTVOLUME)
{
return DismountVolume(hb_parnl(1));
}
HB_FUNC(PREVENTREMOVALOFVOLUME)
{
return PreventRemovalOfVolume(hb_parnl(1), hb_parl(2));
}
HB_FUNC(AUTOEJECTVOLUME)
{
return AutoEjectVolume(hb_parnl(1));
}
HB_FUNC(CLOSEVOLUME)
{
return CloseVolume(hb_parnl(1));
}
Enrico Maria Giordano wrote:Try:
- Code: Select all Expand view RUN
BOOL fRemoveSafely; // = FALSE;
BOOL fAutoEject; // = FALSE;
- Code: Select all Expand view RUN
hb_retl( EjectVolume( ( TCHAR ) *szDrive ) );
Return to FiveWin for Harbour/xHarbour
Users browsing this forum: Google [Bot] and 39 guests