* 29/feb/2004 pdv * PGD_EE means Pretty Good Discriminator of Executable's Environment. * This routine must provide a 'pretty good discriminator' with regard to the executable's environment, that is, * a string that identifies the environment of the executable in such a way that there's a pretty good chance * that it will be another string if the executable is run from another environment. * Here's the logic: * - If it is run from a network drive, then it will be based on the server name, e.g. '\\PC1\'. * - If it is run from a local drive, then it will be the drive's volume name, e.g. 'HD_WinXP'. * - If it is a local drive, but no volume name has been specified so far, then it will be the * the local drive's serial number. * - If no name could be determined (empty result), then it will be 'HUH'. * Why this logic? The idea is that a license file initially comes without this info. On the first usage * this info is added to the license file. If a user wants to steal a copy of the (modified) license file * for usage on another machine, then there will be a 'pretty good' chance that the result of this function * will be different. That fact can be used to deny (full) usage. The only situation that will lead to the same * result is where the new environment is exactly the same with regard to server name or volume name. So be it. * The drawback is that the user will also be denied (full) usage if the application is moved to another location. * The application should then display a messagebox asking the user to write a copy of the original license * key to the application's folder. Big chance that the thief has no original license key! FUNCTION PGD_EE() local lnDrvType, lcResult, lnBufsize, lcBuff, lcExePath, lcDrvLetter, llUNC, llDrive local lcRoot, lcVolName, lnVolSize, lnSerialNO, lnCompLen, lnSysFlags, lcSysName, lnNameSize lcResult = '' lcExePath = addbs( justpath( fullpath( sys( 16, 0 ) ) ) ) llUNC = .f. llDrive = .f. do case case left( lcExePath, 2 ) == '\\' * llUNC = .t. case substr( lcExePath, 2, 1 ) = ':' * * These defines are from F:\Microsoft Visual Studio\VC98\Include\WINBASE.H *#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 * Based on (but not equal to!) <B>Re: How to identify the server name.</B> Thread #817893 Message #817926 * DECLARE INTEGER GetDriveType IN kernel32 STRING RootPath DECLARE INTEGER WNetGetConnection IN mpr STRING lpLocalName, STRING @lpRemoteName, INTEGER @lpnLen lcDrvLetter = left( lcExePath, 1 ) lnDrvType = GetDriveType( lcDrvLetter + ':\' ) if lnDrvType = 4 &&DRIVE_REMOTE * lnBufsize = 250 lcBuff = Replicate( chr(0), lnBufsize ) * if WNetGetConnection( lcDrvLetter + ':', @lcBuff, @lnBufsize ) = 0 * lcExePath = strtran( lcBuff, chr(0), '' ) llUNC = .t. endif else llDrive = .t. endif clear dlls "GetDriveType", "WNetGetConnection" endcase do case case llUNC * lcResult = left( lcExePath, at( '\', lcExePath, 3 ) ) && e.g. '\\PC1\' case llDrive * http://fox.wikis.com/wc.dll?Wiki~GetVolumeInformation~WIN_COM_DNA * DECLARE SHORT GetVolumeInformation IN Win32API ; STRING @lpRootPathName, ; STRING @lpVolumeNameBuffer, ; INTEGER nVolumeNameSize, ; INTEGER @lpVolumeSerialNumber, ; INTEGER @lpMaximumComponentLength, ; INTEGER @lpFileSystemFlags, ; STRING @lpFileSystemNameBuffer, ; INTEGER nFileSystemNameSize STORE 0 TO lnSerialNO, lnCompLen, lnSysFlags STORE SPACE(260) TO lcVolName, lcSysName STORE LEN(lcVolName) TO lnVolSize, lnNameSize lcRoot = lcDrvLetter + ':\' if GetVolumeInformation( ; @lcRoot, @lcVolName, lnVolSize, @lnSerialNO, @lnCompLen, ; @lnSysFlags, @lcSysName, lnNameSize) # 0 * lcResult = strtran( rtrim( lcVolName ), chr(0), '' ) * if empty( lcResult ) lcResult = ltrim( str( lnSerialNO, 20 ) ) endif endif clear dlls "GetVolumeInformation" endcase if empty( lcResult ) lcResult = 'huh' endif RETURN upper( lcResult )