/* **********************************************************************
18/11/2008
Aquí dejaré las funciones genéricas que utilizaré para la gestión de la
protección con USB.
-En W2000 no es operativa para usuarios no Administradores.
-La variable STATIC aUSB contiene el indicador lógico de 'DEMO' en el
primer elemento, y los números de serie i descriptivo (en una array de
2 elementos) de los Pendrive (USB) autorizados para usar la aplicación
sin límites.
-INICIALMENTE el primer elemento de aUSB debe ser siempre .T.
-La función WarningDemo() es la que se puede insertar en CUALQUIER PUNTO
o PUNTOS de la aplicación para verificar/avisar si se trata de una DEMO.
Lo habitual es usarla con el parámetro .T. ( WarningDemo( .T. ) )
Es esta función la que se debe modificar según las necesidades; en mi
caso avisa si quedan menos de 2 minutos de demostración y pasados 5
minutos cierra la aplicación.
Otra opción es modificar esta función para que en base al valor de
retorno (.T. o .F.), realizar lo que queramos en cualquier lugar de
nuestra aplicación.
-La función cGetSerialProtect() es la que nos dirá el número de serie
de el USB que escojamos de la lista que nos enseñe.
Se puede usar en un menú de configuración de la aplicación para que el
usuario nos facilite el número de serie del USB que utilizará.
********************************************************************** */
#include "FiveWin.ch"
#define DRIVE_REMOVABLE 2
/* ************************ ATENCIÓ ***********************
Números de sèrie d'USB admesos.
El 1er. element indica si la verificació ha tingut èxit.
Los elementos posteriores son arrays de 2 elemntos con
los números de serie y descriptivos de los USB
autorizados.
Inicialmente el 1er. elemento SIEMPRE debe de ser .T.
----------------------------------------------------- */
STATIC aUSB := { .T., ;
{"077522058501D5A6", "Sense descriptiu" }, ;
{"0775030772C2BFF2", "Sense descriptiu" }, ;
{"07871044024E", "EMTEC 8 Gb (marrón)" }, ;
{"000AEB91EBF75A891D010114", "Kingston 16 Gb extensible (Plàstic negre)" }, ;
{"0799120338141B2D", "Imation Mini de 4 Gb (metall plata, Plàstic negre)" }, ;
{"W6YFEDS7NDAQCNKK", "Susana"} ;
}
/* *************************** */
/* *************************** */
FUNCTION QuitApl()
CLOSE ALL
PostQuitMessage( 0 )
sysrefresh()
__quit()
Return NIl
/* *************************** */
/* *************************** */
/* Mostra missatge per indicar que s'està en modus DEMO.
-------------------------------------------------- */
FUNCTION WarningDemo( lVerifica )
// Dia i hora inicial.
STATIC aTimeInfo := { 0, 0 }
// 3 minuts (en segons)
Local Limita := 180
// 5 minuts (en segons)
Local Limitb := 300
Local SecFromStart := 0
If lVerifica .and. !lIsDemo( )
aUSB[1] := lIsOkUSB()
EndIf
If lIsDemo()
// Si no s'havia capturat el moment inicial, es captura ara.
If aTimeInfo[2] = 0
aTimeInfo[1] := Date()
aTimeInfo[2] := Seconds()
MsgAlert( "Aplicació en modus DEMOSTRACIÓ." + CRLF + CRLF + ;
"TOTES les opcions són COMPLETAMENT operatives." + CRLF + ;
"La limitació és de " + Str( Limitb/60, 2, 0) + " minuts per poder operar.", ;
" A T E N C I Ó !" )
EndIf
SecFromStart := SecsFromStart( aTimeInfo[1], aTimeInfo[2] )
If SecFromStart > Limitb
MsgAlert( "Ha esgotat el temps de DEMOSTRACIÓ", " A T E N C I Ó !" )
//QUIT
// Es tanca l'aplicació.
QuitApl()
ElseIf SecFromStart > Limita
MsgAlert( "Queden " + Str( (Limitb - SecFromStart) / 60, 1, 0 ) + " minuts de DEMOSTRACIÓ", " A T E N C I Ó !" )
EndIf
EndIf
Return aUSB[1]
/* *************************** */
/* *************************** */
STATIC function SecsFromStart( dInitDate, nInitSecs ) // by hDC
local nSeconds:= Seconds()
local nDays := Date() - dInitDate
if ValType( nDays ) == "D" // C3 temporary workaround
nDays = Day( Date() ) - Day( dInitDate )
endif
if nDays < 0 // Surely you change the date after the beginning of the system
return 0
endif
if nDays > 0
nDays--
return ( 86399 - nInitSecs ) + ( nDays * 86399 ) + nSeconds
endif
return nSeconds - nInitSecs
/* *************************** */
/* *************************** */
/* ************************************************
Nos indica si se trata de una versión DEMO o no.
--------------------------------------------- */
FUNCTION lIsDemo( )
/* La obtención del número de serie del USB no funciona bajo W2000 si no se
es administrador del sistema, de ahí que si se está bajo W2000 se de por
válido aún sin tener el USB conectado.
*/
Return !( aUSB[1] .or. IsWin2000() )
/* *************************** */
/* *************************** */
/* *********************************************************************************
Chequea si se encuentra instalado el USB correspondiente a uno de los números de
serie recibidos.
ATENCIÓN: de la array aUSB el primer elemento no es tenido en
cuenta ya que se trata del indicador de DEMO (.T. o .F.).
------------------------------------------------------------------------------ */
STATIC FUNCTION lIsOkUSB()
Local nContador := 0
/* El 1er. element és l'indicador de DEMO.
----------------------------------- */
For nContador := 2 to Len( aUSB )
If cNumUSB2LetUSB( aUSB[ nContador ][1] ) <> ""
Exit
EndIf
EndFor
Return !( nContador > Len( aUSB ) )
/* *************************** */
/* *************************** */
/* *****************************************************************
A partir de un número de serie obtiene la letra del Pendrive USB.
-------------------------------------------------------------- */
STATIC FUNCTION cNumUSB2LetUSB( cNumUSB )
Local cLetter := ""
Local nBitDrives := GetLogicalDrives()
Local nContador := 0
Local cDrive := ""
For nContador := 1 to 32
If lAnd( nBitDrives, 2 ^ ( nContador - 1 ) )
cDrive = Chr( Asc( "A" ) - 1 + nContador ) + ":\"
If nContador != 1 .and. GetDriveType( cDrive ) == DRIVE_REMOVABLE
If GetUSBSerial( cDrive ) == cNumUSB
cLetter := cDrive
Exit
EndIf
Endif
Endif
Next
Return cLetter
/* *************************** */
/* *************************** */
/* ***********************************************************************
A partir d'una lletra d'un USB inicia la cerca del seu número de sèrie.
-------------------------------------------------------------------- */
STATIC FUNCTION GetUSBSerial( cDrive )
Local oLoc := CreateObject( "wbemScripting.SwbemLocator" )
Local oSrv := oLoc:ConnectServer()
Local oJobs := oSrv:ExecQuery( "SELECT * FROM Win32_LogicalDiskToPartition" )
Local oJob
Local cDriveNumber
cDrive = Upper( cDrive )
If Len( cDrive ) == 1
cDrive += ":"
Endif
If Len( cDrive ) > 2
cDrive = SubStr( cDrive, 1, 2 )
Endif
For each oJob in oJobs
If cDrive == StrToken( oJob:Dependent, 2, '"' )
cDriveNumber = SubStr( StrToken( StrToken( oJob:Antecedent, 2, '"' ), 1, "," ), 7 )
return GetSerial( oSrv, cDriveNumber )
Endif
Next
Return ""
/* *************************** */
/* *************************** */
/* *********************************************************
Cerca a partir d'una lletra d'USB el seu número de sèrie.
------------------------------------------------------ */
STATIC FUNCTION GetSerial( oSrv, cDriveNumber )
Local aDrives := oSrv:ExecQuery( "SELECT * FROM Win32_DiskDrive" )
Local oDrive, cSerial := ""
For each oDrive in aDrives
If oDrive:Name == "\\.\PHYSICALDRIVE" + cDriveNumber .and. ;
oDrive:InterfaceType == "USB"
cSerial = oDrive:PNPDeviceID
cSerial = SubStr( cSerial, 1, RAt( "&", cSerial ) - 1 )
cSerial = SubStr( cSerial, RAt( "&", cSerial ) + 1 )
If At( "\", cSerial ) != 0
cSerial = SubStr( cSerial, At( "\", cSerial ) + 1 )
Endif
Return cSerial
Endif
Next
Return cSerial
/* *************************** */
/* *************************** */
/* *****************************************************************************
Torna el número de sèrie de l'USB escollit per ser la 'motxila' del programa.
-------------------------------------------------------------------------- */
FUNCTION cGetSerialProtect()
Local cDriveUSB := ""
Local oClp := Nil
If ( cDriveUSB := cSelectUSB( .T. ) ) <> ""
/*
MsgInfo( "Identificadors autoritzats: " + cNumUSB() + CRLF + CRLF + ;
"L'identificador de " + cDriveUSB + " és: " + GetUSBSerial( cDriveUSB ) + CRLF + CRLF + ;
If( AT( GetUSBSerial( cDriveUSB ), cNumUSB() ) > 0, "SI", "NO") + " està autoritzat.", ;
"A T E N C I Ó !" )
*/
If MsgYesNo( "Identificadors autoritzats: " + cNumUSB() + CRLF + CRLF + ;
"L'identificador de " + cDriveUSB + " és: " + GetUSBSerial( cDriveUSB ) + CRLF + ;
"El vol copiar al ClipBoard?" + CRLF + CRLF + ;
If( AT( GetUSBSerial( cDriveUSB ), cNumUSB() ) > 0, "SI", "NO") + " està autoritzat.", ;
"ATENCIÓ !" )
DEFINE CLIPBOARD oClp FORMAT TEXT
//cClp = oClp:GetText()
oclp:Open()
Oclp:Empty()
SetClipboardData( 1, GetUSBSerial( cDriveUSB ) )
oClp:End()
EndIf
//If( AT( GetUSBSerial( cDriveUSB ), cNumUSB() ) > 0, aUSB[1] := .T., Nil )
EndIf
Return Nil
/* *************************** */
/* *************************** */
FUNCTION cSelectUSB( lMensaje )
Local aDriveUSB := {}
Local nDriveUSB := 0
Local cDriveUSB := ""
Local nContador := 0
aDriveUSB := aUSBDrive()
If Len( aDriveUSB ) = 0
If lMensaje
MsgAlert( "No hi han unitats USB disponibles, insereixi una unitat USB.", "A T E N C I Ó !" )
EndIf
Else
//AEval( aDriveUSB, { |DriveUSB| DriveUSB := "&" + DriveUSB } )
For nContador := 1 To Len( aDriveUSB )
aDriveUSB[ nContador ] := "&" + aDriveUSB[ nContador ]
EndFor
nDriveUSB := Alert( "Unitats USB disponibles:", aDriveUSB, "Esculleixi una unitat USB" )
If nDriveUSB > 0
cDriveUSB := SubStr( aDriveUSB[ nDriveUSB ], 2 )
EndIf
EndIf
//Traza(1, "cDriveUSB=", cDriveUSB)
//Traza(1, "aDriveUSB[ nDriveUSB ]=", aDriveUSB[ nDriveUSB ])
Return cDriveUSB
/* *************************** */
/* *************************** */
/* ******************************************
Devuelve un CADENA de los USB autorizados.
--------------------------------------- */
STATIC FUNCTION cNumUSB()
Local nContador := 0
Local cUSB := ""
/* El 1er. element és l'indicador de DEMO.
----------------------------------- */
For nContador := 2 to Len( aUSB )
cUSB = cUSB + "," + aUSB[ nContador ][1]
EndFor
Return SubStr( cUSB, 2)
/* *************************** */
/* *************************** */
/* ************************************
Torna una array dels USB connectats.
--------------------------------- */
STATIC FUNCTION aUSBDrive()
Local nBitDrives := GetLogicalDrives()
Local nContador := 0
Local cDrive := ""
Local aDrives := {}
For nContador := 1 to 32
If lAnd( nBitDrives, 2 ^ ( nContador - 1 ) )
cDrive = Chr( Asc( "A" ) - 1 + nContador ) + ":\"
If nContador != 1 .and. GetDriveType( cDrive ) == DRIVE_REMOVABLE
AAdd( aDrives, cDrive )
Endif
Endif
Next
Return aDrives
/* *************************** */