I read from forum and found TUpdate class. But I cannot build? It show the error as below
--------------------Configuration: tftp - Release--------------------
xHarbour 1.2.3 Intl. (SimpLex) (Build 20161218)
Copyright 1999-2016, http://www.xharbour.org http://www.harbour-project.org/
Embarcadero C++ 7.00 for Win32 Copyright (c) 1993-2015 Embarcadero Technologies, Inc.
tftp.c:
Error E2209 D:\\FWH1707\\samples\\tftp.prg 428: Unable to open include file 'WinTen.h'
Warning W8019 d:\bcc7\include\windows\sdk\winnt.h 14984: Code has no effect in function TpDestroyCallbackEnviron
Warning W8075 D:\\FWH1707\\samples\\tftp.prg 439: Suspicious pointer conversion in function HB_FUN_FILETIMES
Warning W8060 D:\\FWH1707\\samples\\tftp.prg 545: Possibly incorrect assignment in function HB_FUN_ISADMIN
Warning W8060 D:\\FWH1707\\samples\\tftp.prg 559: Possibly incorrect assignment in function HB_FUN_ISADMIN
Warning W8060 D:\\FWH1707\\samples\\tftp.prg 569: Possibly incorrect assignment in function HB_FUN_ISADMIN
Warning W8060 D:\\FWH1707\\samples\\tftp.prg 577: Possibly incorrect assignment in function HB_FUN_ISADMIN
*** 1 errors in Compile ***
Turbo Incremental Link 6.70 Copyright (c) 1997-2014 Embarcadero Technologies, Inc.
Fatal: Unable to open file 'TFTP.OBJ'
tftp.EXE - 2 error(s), 6 warning(s)
This is the code that I copy from the forum.
- Code: Select all Expand view
- #include 'fivewin.ch'
#define INTERNET_FLAG_PASSIVE 0x08000000 // used for FTP connections - 134217728
#define ZTRIM( cString ) Left( cString, At( Chr( 0 ), cString ) - 1 )
FUNCTION main()
LOCAL oUpdate
LOCAL cFtp := "easyfo.dyndns.info"
LOCAL cUser := "Administrator" // i insert my user password
LOCAL cPW := "xxxxxxx" // I insert my password
LOCAL cFtpDir := "/crptform/" // "ftp.eoeo.it/wp-content/uploads/downloads/2012/04/"
LOCAL cUpdFile := "rmtyavl.rpt"
LOCAL cLocalDir := "c:\temp"
LOCAL nFlags := INTERNET_FLAG_PASSIVE // <SpecialConnectionFlags> // use 134217728 to set passive mode
oUpdate := TUpdate():New(cFtp, cUser, cPW, cFtpDir, cUpdFile, cLocalDir)
oUpdate:nFlags := nFlags
oUpdate:Update ()
oUpdate:End ()
RETURN (nil)
/*
Class TUpdate - application update over ftp
--------------------------------------------------
(based on a function from Biel Maimo)
Version 1.2
(c) Stefan Haupt 2012
Description: This is a claas to update your application over a Ftp-Server.
It?s very easy to use, I think the code is self explaining. You
just need some vars to be set, the update is automatically done.
That means your application is closed, the files are copied and
your application is restarted.
Sample:
FUNCTION Update ()
LOCAL oUpdate
LOCAL cFtp := "YourFtpServer"
LOCAL cUser := "YourLoginName"
LOCAL cPW := "YourPassword"
LOCAL cFtpDir := "YourUpdateFolderOnFtp"
LOCAL cUpdFile := "NameOfTheUpdatefile"
LOCAL cLocalDir := "NameOfTheLocalDir"
LOCAL nFlags := <SpecialConnectionFlags> // use 134217728 to set passive mode
oUpdate := TUpdate():New(cFtp, cUser, cPW, cFtpDir, cUpdFile, cLocalDir+"Updates\")
oUpdate:nFlags := nFlags
oUpdate:Update ()
oUpdate:End ()
RETURN (nil)
****************************************************************************
Remarks: If you want to use the passive mode in your ftp connection, you have
to update the class TFtp that comes with fwh.
Just replace the method new with this one:
METHOD New( cFTPSite, oInternet, cUserName, cPassword, nFlags ) CLASS TFTP
DEFAULT nFlags := 0
::oInternet = oInternet
::cSite = cFTPSite
::cUserName = cUserName
::cPassword = cPassword
if oInternet:hSession != nil
::hFTP = InternetConnect( oInternet:hSession, cFTPSite, FTP_PORT,;
::cUserName, ::cPassword,;
INTERNET_SERVICE_FTP, nFlags, 0 )
AAdd( oInternet:aFTPs, Self )
endif
return Self
****************************************************************************/
CLASS TUpdate
DATA oInternet AS OBJECT
DATA oFtp AS OBJECT
DATA nFlags AS NUMERIC
DATA cIP AS CHARACTER // Ftp-Server
DATA cUser AS CHARACTER // login name
DATA cPW AS CHARACTER // password
DATA cFtpFolder AS CHARACTER // folder on ftp where update files are
DATA cZipFile AS CHARACTER // name of the update file (must be zip)
DATA cLocalDir AS CHARACTER // local folder where the update files are copied
DATA cAppDir AS CHARACTER // applications folder
DATA cAppFile AS CHARACTER // name of the application
DATA aUpdateFiles AS ARRAY // files in the zip
DATA cUpdateBatch AS CHARACTER // path and name of the update batchfile
//DATA lRestartApp AS LOGICAL INIT .f.
DATA nError INIT 0 // common error
METHOD New () CONSTRUCTOR // create a new instance, initialize all vars
METHOD End () // close the connection
METHOD Update () // update the application
//METHOD Setup () HIDDEN // all other methods are only for internal use
METHOD Download () HIDDEN
METHOD DownloadFile () HIDDEN
METHOD UnpackFile () HIDDEN
METHOD WriteBatch () HIDDEN
ENDCLASS
//----------------------------------------------------------------------
METHOD New (cIP, cUser, cPW, cFTPFolder, cZIPFile, cLocalDir, nFlags) CLASS TUpdate
DEFAULT cIP := "localhost",;
cUser := "anonymous",;
cPW := "anonymous@localhost",;
cFtpFolder := "/",;
cZipFile := "",;
cLocalDir := cFilePath( GetModuleFileName( GetInstance() ) ) + "Updates\" ,;
nFlags := 0
::cIP := cIp
::nFlags := nFlags // special flags for ftp, eg. passive mode
::cUser := cUser
::cPW := cPW
::cFtpFolder := cFtpFolder
::cZipFile := cZipFile
::cAppFile := GetModuleFileName( GetInstance() )
::cAppDir := cFilePath (GetModuleFileName( GetInstance() ) )
::cLocalDir := cLocalDir
::cUpdateBatch := ::cLocalDir + "Update.cmd"
IF !IsDir (::cLocalDir) // create updatefolder
IF (::nError := MakeDir (::cLocalDir)) != 0
MsgAlert ("Updateverzeichnis konnte nicht erstellt werden","Programmaktualisierung")
ENDIF
ENDIF
IF .f. // !IsAdmin () // n
::nError := 1
MsgAlert ("Sie ben?tigen Administratorrechte f?r dieses Update","Programmaktualisierung")
ENDIF
RETURN (self)
//----------------------------------------------------------------------
METHOD End ()
LOCAL bClose := {|| ::oFtp:END(), ::oInternet:END()}
IF ::nError = 0
MsgRun ("Verbindung beenden...",,bClose)
ENDIF
RETURN (nil)
//----------------------------------------------------------------------
METHOD Update () CLASS TUpdate
LOCAL cFile, nSize, dDate, cTime, aTime
LOCAL cFtpFile, dFtpDate, cFtpTime, nFtpSize
LOCAL aF := {}, aFiles:={}
LOCAL lIsFile := .f. // update file exists ?
LOCAL aUpdate := {}, lSuccess := .f.
LOCAL bConnect := {|| ::oInternet := tInternet():New(),;
::oFtp := tFtp():New (::cIp, ::oInternet, ::cUser, ::cPW, ::nFlags) }
IF ::nError != 0
Return (nil)
ENDIF
IF !Empty (::cIP)
CursorWait ()
MsgRun ("Verbindung aufbauen...",,bConnect)
CursorArrow ()
IF Empty (::oFtp:hFtp)
MsgStop ("Verbindung zum Server gescheitert", "Programmaktualisierung")
//::oFtp:END()
//::oInternet:END()
ELSE
::oFtp:SetCurrentDirectory( ::cFtpFolder )
// cDir := oFtp:GetCurrentDirectory()
aFiles := ::oFtp:Directory (::cZipFile) // all files in ftp folder
IF !Empty (aFiles)
AEval (aFiles, {|x| Aadd (aF, {ZTRIM (x[1]), x[2], x[3], x[4] } )} )
cFtpFile := aF[1,1] // filename
dFtpDate := aF[1,3] //
cFtpTime := aF[1,4] //
nFtpSize := aF[1,2] //
cFile := ::cLocalDir + ::cZipFile // local file
IF File (cFile)
aTime := FileTimes ( cFile, 1 )
dDate := CToD (Str( aTime[ 3 ], 2 ) + "/" + StrZero( aTime[ 2 ], 2 ) + "/" + StrZero( aTime[ 1 ], 4 ))
cTime := StrZero ( aTime[ 4 ], 2 ) + ":" + StrZero( aTime[ 5 ], 2 ) + ":" + StrZero( aTime[ 6 ], 2 )
nSize := FileSize ( cFile )
lIsFile := .t.
ENDIF
IF !lIsFile .or. ; // updatefile not present
(dDate < dFtpDate).OR.; // copmpare date and time
(dDate == dFtpDate .AND. (TimeToSec (cTime ) < TimeToSec (cFtpTime) ) )
IF MsgYesNo('Neue Version vorhanden, Aktualisierung durchf?hren ?',;
"?berpr?fung auf neue Programmversion")
IF ::Download (cFtpFile , cFile, nFtpSize, dFtpDate, cFtpTime)
::oFtp:END()
::oInternet:END()
IF ::WriteBatch ()
CLOSE ALL
WinExec (::cUpdateBatch)
PostQuitMessage(0)
QUIT
ELSE
MsgStop ("Aktualisierung fehlgeschlagen", "Programmaktualisierung")
ENDIF
ENDIF
ENDIF // MsgYesNo
ELSE
MsgInfo ("Die Programmversion ist aktuell","Programmaktualisierung")
ENDIF // IF (dDate < dFtpDate).OR
ELSE
MsgInfo ("Die Programmversion ist aktuell","Programmaktualisierung")
ENDIF // !Empty (aFiles)
ENDIF // Empty (::oFtp:hFtp)
ENDIF // !Empty (::cIP)
RETURN (nil)
//----------------------------------------------------------------------
METHOD Download (cSource, cTarget, nSize, dDate, cTime) CLASS TUpdate
LOCAL oDlg, oSay1, oSay2, oBtnCancel, oMeter1, oMeter2, nMeter1, nMeter2
LOCAL lEnd:=.F., nAmount, lOk:=.F., lValRet:=.F.
LOCAL hFile
LOCAL cError1 := "Fehler beim Download"
LOCAL cError2 := "Fehler beim Entpacken"
// orange
// GRADIENT TRACK { { 1/2, nRGB( 198, 203, 213 ), nRGB( 219, 224, 233 ) },;
// { 1/2, nRGB( 224, 238,237 ), nRGB( 224, 238,237 ) } } ;
DEFINE DIALOG oDlg TITLE "Programm-Aktualisierung" FROM 0,0 TO 10,50
@ 0.5,01 SAY oSay1 PROMPT "Dateien herunterladen" SIZE 80,8 OF oDlg
@ 1.2,01 METEREX oMeter1 VAR nMeter1 SIZE 180,10 TOTAL nSize ;
GRADIENT TRACK { { 1/2, nRGB( 198, 203, 213 ), nRGB( 219, 224, 233 ) },;
{ 1/2, nRGB( 224, 238,237 ), nRGB( 224, 238,237 ) } } ;
OF oDlg
@ 02 ,01 SAY oSay2 PROMPT "Entpacken" OF oDlg
@ 2.7,01 METEREX oMeter2 VAR nMeter2 SIZE 180,10 TOTAL 0 ;
GRADIENT TRACK { { 1/2, nRGB( 198, 203, 213 ), nRGB( 219, 224, 233 ) },;
{ 1/2, nRGB( 224, 238,237 ), nRGB( 224, 238,237 ) } } ;
OF oDlg
@ 3.2,12 BUTTON oBtnCancel PROMPT "&Abbrechen" ACTION ( lEnd := .t., SysRefresh(), oDlg:End() )
oDlg:bStart := {|| lOk := ::DownloadFile ( cSource, nSize, oMeter1, @lEnd, oDlg, cTarget ),;
IIF (lOk, SetFDaTi (cTarget, dDate, cTime), MsgStop (cError1) ),;
IIF (lOk, lOk := ::UnPackFile (cTarget, oMeter2), ),;
IIF (lOk, (oBtnCancel:SetText( "&Neu starten" ), oBtnCancel:bAction := {|| lEnd := .f., oDlg:End()} ),;
MsgStop (cError2) ) }
ACTIVATE DIALOG oDlg CENTERED
IF !lEnd .AND. lOk
lValRet:=.T.
ENDIF
RETURN (lValRet)
//----------------------------------------------------------------------------------------
METHOD DownloadFile ( cSource, nSize, oMeter, lEnd, oDlg, cTarget ) CLASS TUpdate
LOCAL oFile, hTarget, lValRet:=.F.
LOCAL nBufSize,cBuffer,nBytes := 0, nTotal := 0//, nFile:=0
LOCAL lRet := .f.
nBufSize := 4096
cBuffer := Space(nBufSize)
hTarget := FCreate (cTarget)
oFile := tFtpFile():New( cSource, ::oFtp )
oFile:OpenRead()
SysRefresh()
WHILE ( nBytes := Len( cBuffer := oFile:Read( nBufSize ) ) ) > 0 .and. !lEnd
FWrite( hTarget, cBuffer, nBytes )
nTotal += nBytes
oMeter:Set( nTotal )
SysRefresh()
END
FClose( hTarget )
oFile:End()
IF nTotal > 0
lRet := (nTotal==nSize)
ENDIF
RETURN (lRet)
//----------------------------------------------------------------------------------------
METHOD UnPackFile (cZip, oMeter) CLASS TUpdate
LOCAL aUpdate :={}, aFiles := {}, aUnzip := {}, n := 1
LOCAL lSuccess := .f.
LOCAL bProgress := {|| oMeter:Set (n++) }
LOCAL cPath := cFilePath (cZip)
aUpdate := hb_GetFilesInZip( cZip, .t. )
IF Len (aUpdate) > 0
AEval (aUpdate, {|x| Aadd (aFiles, {x[1], x[6], x[7]} ) } )
AEval (aUpdate, {|x| Aadd (aUnzip, x[1]) } )
oMeter:nTotal:= Len (aUnzip)
lSuccess := hb_UnZipFile( cZip , ;
bProgress,; //
nil,; // lWithSubDir
nil,; // cPassword
cPath,; // cZipDir
aUnzip ,;
nil ) // bFileProgress
AEval (aFiles, {|x| SetFDaTi (cPath+x[1], x[2], x[3]) } ) // restore original date and time !!
ENDIF
::aUpdateFiles := AClone (aUnzip)
RETURN (lSuccess)
//-------------------------------------------------------------------------------
METHOD WriteBatch () CLASS TUpdate
LOCAL hBatch,i
LOCAL cBatch, cCopy := "", cDel := "", cS := ["]
FErase (::cUpdateBatch)
FOR i := 1 TO Len (::aUpdateFiles)
cCopy += "Copy /Y /B /V " + cS + ::cLocalDir + ::aUpdateFiles[i] + cS + " " + cS + ::cAppDir + cS + " > NUL" + CRLF
cDel += "Del /F " + cS + ::cLocalDir + ::aUpdateFiles[i] + cS + " >NUL" + CRLF
NEXT
cBatch := "@Echo off"+CRLF+;
"echo Updating ..."+CRLF+;
"ping -n 2 127.0.0.1 > NUL"+CRLF+; // waiting 2 secs
cCopy +;
"Start " + cS + "update" + cS + " " + cS + ::cAppFile + cS + CRLF +;
cDel +;
"EXIT"
hBatch := FCreate (::cUpdateBatch,0)
FWrite (hBatch, cBatch)
FClose (hBatch)
RETURN (FError() = 0)
// convert hours to seconds
//--------------------------------------------------------
STATIC FUNCTION TimeToSec( cTime )
local nSec := 0, nLen, i, aLim, aMod, nInd, n
if cTime == NIL
nSec := seconds()
elseif HB_ISCHAR( cTime )
nLen := len( cTime )
if ( nLen + 1 ) % 3 == 0 .and. nLen <= 11
nInd := 1
aLim := { 24, 60, 60, 100 }
aMod := { 3600, 60, 1, 1/100 }
for i := 1 to nLen step 3
if isdigit( substr( cTime, i, 1 ) ) .and. ;
isdigit( substr( cTime, i + 1, 1 ) ) .and. ;
( i == nLen - 1 .or. substr( cTime, i + 2, 1 ) == ":" ) .and. ;
( n := val( substr( cTime, i, 2 ) ) ) < aLim[ nInd ]
nSec += n * aMod[ nInd ]
else
nSec := 0
exit
endif
++nInd
next
endif
endif
RETURN (Round( nSec, 2)) /* round FL val to be sure that you can compare it */
//----------------------------------------------------------------------
#pragma BEGINDUMP
#include <WinTen.h>
#include <Windows.h>
#include <mapiwin.h>
#include <hbApi.h>
#include <CommDlg.h>
extern LPSTR LToStr( long w );
//nTime 1=Last Update, 2=Last Acces, 3=Creation, defecto last update
HB_FUNC( FILETIMES ) // params cFileName, nTime --> { nYear, nMonth, nDay, nHour, nMin, nSec }
{
LPSTR cFileName = hb_parc( 1 ) ;
int nTime = ( ISNUM( 2 ) ? hb_parni( 2 ) : 1 ) ; // defaults to 1
FILETIME ftCreate, ftAccess, ftWrite ;
SYSTEMTIME stTime ;
BOOL bRet ;
HANDLE hFile = CreateFile( cFileName, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 ) ;
if( ! hFile )
return ;
GetFileTime( (HANDLE) hFile, &ftCreate, &ftAccess, &ftWrite ) ;
switch( nTime )
{
case 1 : // last update
FileTimeToSystemTime( &ftWrite, &stTime ) ;
break ;
case 2 : // last access
FileTimeToSystemTime( &ftAccess, &stTime ) ;
break ;
case 3 : // creation
FileTimeToSystemTime( &ftCreate, &stTime ) ;
break ;
default : // last update
FileTimeToSystemTime( &ftWrite, &stTime ) ;
break ;
}
SystemTimeToTzSpecificLocalTime( NULL, &stTime, &stTime ) ;
CloseHandle( hFile ) ;
hb_reta( 6 ) ;
hb_storni( stTime.wYear, -1, 1 ) ;
hb_storni( stTime.wMonth, -1, 2 ) ;
hb_storni( stTime.wDay, -1, 3 ) ;
hb_storni( stTime.wHour, -1, 4 ) ;
hb_storni( stTime.wMinute, -1, 5 ) ;
hb_storni( stTime.wSecond, -1, 6 ) ;
}
#define FA_RDONLY 1 /* R */
#define FA_HIDDEN 2 /* H */
#define FA_SYSTEM 4 /* S */
#define FA_LABEL 8 /* V */
#define FA_DIREC 16 /* D */
#define FA_ARCH 32 /* A */
#define FA_NORMAL 0
HB_FUNC(FILESIZE)
{
LPCTSTR szFile;
DWORD dwFlags=FILE_ATTRIBUTE_ARCHIVE;
HANDLE hFind;
WIN32_FIND_DATA hFilesFind;
int iAttr;
if (hb_pcount() >=1){
szFile=hb_parc(1);
if (ISNUM(2)) {
iAttr=hb_parnl(2);
}
else{
iAttr=63;
}
if( iAttr & FA_RDONLY )
dwFlags |= FILE_ATTRIBUTE_READONLY;
if( iAttr & FA_HIDDEN )
dwFlags |= FILE_ATTRIBUTE_HIDDEN;
if( iAttr & FA_SYSTEM )
dwFlags |= FILE_ATTRIBUTE_SYSTEM;
if( iAttr & FA_NORMAL )
dwFlags |= FILE_ATTRIBUTE_NORMAL;
hFind = FindFirstFile(szFile,&hFilesFind);
if (hFind != INVALID_HANDLE_VALUE){
if (dwFlags & hFilesFind.dwFileAttributes) {
if(hFilesFind.nFileSizeHigh>0)
hb_retnl((hFilesFind.nFileSizeHigh*MAXDWORD)+hFilesFind.nFileSizeLow);
else
hb_retnl(hFilesFind.nFileSizeLow);
}
else
hb_retnl(-1);
}
}
}
HB_FUNC (ISADMIN)
{
HANDLE hToken;
PTOKEN_GROUPS pGroupInfo;
DWORD dwSize = 0, dwResult;
DWORD nError = 0, i;
BOOL lError, lAdMin = FALSE;
LPSTR cFunc = "";
PSID psidAdmin;
CHAR cMess[200];
SID_IDENTIFIER_AUTHORITY SystemSidAuthority= SECURITY_NT_AUTHORITY;
if ( lError = (! OpenProcessToken(GetCurrentProcess(),TOKEN_QUERY,&hToken) ))
{
cFunc = "OpenProcessToken";
nError = GetLastError();
if (nError == ERROR_CALL_NOT_IMPLEMENTED)
{
hb_retl( TRUE );
return;
}
}
if ( ! lError && ! GetTokenInformation(hToken, TokenGroups, NULL, dwSize, &dwSize))
{
dwResult = GetLastError();
if( lError=(dwResult != ERROR_INSUFFICIENT_BUFFER ))
{
nError = dwResult;
cFunc = "GetTokenInformation";
}
}
if ( ! lError )
{
pGroupInfo = (PTOKEN_GROUPS) GlobalAlloc( GPTR, dwSize );
if( lError = (! GetTokenInformation(hToken, TokenGroups, pGroupInfo, dwSize, &dwSize ) ))
{
nError = GetLastError();
cFunc = "GetTokenInformation";
}
}
if ( ! lError )
if ( lError = (! AllocateAndInitializeSid ( &SystemSidAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &psidAdmin) ))
{
nError = GetLastError();
cFunc = "AllocateAndInitializeSid";
}
if ( ! lError )
{
for( i=0; i<pGroupInfo->GroupCount; i++)
{
if ( EqualSid(psidAdmin, pGroupInfo->Groups[i].Sid) )
{
lAdMin = TRUE;
break;
}
}
}
else
{
cMess[0]=0;
lstrcat(cMess,"Error calling ");
lstrcat(cMess,cFunc);
lstrcat(cMess,": ");
lstrcat(cMess,LToStr(nError));
MessageBox(GetActiveWindow(),cMess,"Attention", MB_OK);
}
if (psidAdmin)
FreeSid(psidAdmin);
if ( pGroupInfo )
GlobalFree( pGroupInfo );
CloseHandle( hToken );
hb_retl( lAdMin );
}
#pragma ENDDUMP