Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
core
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
LibreOffice
core
Commits
7eca4fa0
Kaydet (Commit)
7eca4fa0
authored
Ara 27, 2016
tarafından
Markus Mohrhard
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
get the update service working
Change-Id: I25921090083f20c4bb416f9cfdd5ec6400a27a21
üst
19066caf
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
221 additions
and
105 deletions
+221
-105
Repository.mk
Repository.mk
+3
-0
Executable_update_service.mk
onlineupdate/Executable_update_service.mk
+28
-0
Module_onlineupdate.mk
onlineupdate/Module_onlineupdate.mk
+1
-0
certificatecheck.cxx
onlineupdate/source/service/certificatecheck.cxx
+18
-18
maintenanceservice.cxx
onlineupdate/source/service/maintenanceservice.cxx
+37
-33
registrycertificates.cxx
onlineupdate/source/service/registrycertificates.cxx
+60
-27
servicebase.cxx
onlineupdate/source/service/servicebase.cxx
+11
-12
servicebase.hxx
onlineupdate/source/service/servicebase.hxx
+1
-1
serviceinstall.cxx
onlineupdate/source/service/serviceinstall.cxx
+0
-0
windowsHelper.hxx
onlineupdate/source/service/windowsHelper.hxx
+48
-0
workmonitor.cxx
onlineupdate/source/service/workmonitor.cxx
+14
-14
No files found.
Repository.mk
Dosyayı görüntüle @
7eca4fa0
...
...
@@ -93,6 +93,9 @@ $(eval $(call gb_Helper_register_executables_for_install,SDK,sdk, \
$(eval $(call gb_Helper_register_executables_for_install,OOO,brand, \
$(if $(ENABLE_ONLINE_UPDATE_MAR),\
mar \
$(if $(filter WNT,$(OS)), \
update_service \
) \
updater )\
$(call gb_Helper_optional,BREAKPAD,minidump_upload) \
$(call gb_Helper_optional,FUZZERS,wmffuzzer) \
...
...
onlineupdate/Executable_update_service.mk
Dosyayı görüntüle @
7eca4fa0
...
...
@@ -9,16 +9,44 @@
$(eval $(call gb_Executable_Executable,update_service))
$(eval $(call gb_Executable_set_targettype_gui,update_service,YES))
$(eval $(call gb_Executable_set_include,update_service,\
-I$(SRCDIR)/onlineupdate/source/libmar/src/ \
-I$(SRCDIR)/onlineupdate/source/libmar/verify/ \
-I$(SRCDIR)/onlineupdate/source/libmar/sign/ \
-I$(SRCDIR)/onlineupdate/source/update/common/ \
$$(INCLUDE) \
))
$(eval $(call gb_Executable_use_static_libraries,update_service,\
updatehelper \
winhelper \
))
$(eval $(call gb_Executable_add_libs,update_service,\
ws2_32.lib \
Crypt32.lib \
shell32.lib \
wintrust.lib \
version.lib \
wtsapi32.lib \
userenv.lib \
shlwapi.lib \
ole32.lib \
rpcrt4.lib \
comctl32.lib \
shlwapi.lib \
kernel32.lib \
advapi32.lib \
))
$(eval $(call gb_Executable_add_defs,update_service,\
-DUNICODE \
))
$(eval $(call gb_Executable_add_ldflags,update_service,\
/ENTRY:wmainCRTStartup \
))
$(eval $(call gb_Executable_add_cxxobjects,update_service,\
...
...
onlineupdate/Module_onlineupdate.mk
Dosyayı görüntüle @
7eca4fa0
...
...
@@ -18,6 +18,7 @@ $(eval $(call gb_Module_add_targets,onlineupdate,\
StaticLibrary_winhelper )\
Executable_mar \
Executable_updater \
Executable_update_service \
))
endif
...
...
onlineupdate/source/service/certificatecheck.cxx
Dosyayı görüntüle @
7eca4fa0
...
...
@@ -21,15 +21,15 @@ static const int ENCODING = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
*
* @param filePath The PE file path to check
* @param infoToMatch The acceptable information to match
* @return ERROR_SUCCESS if successful, ERROR_NOT_FOUND if the info
* @return ERROR_SUCCESS if successful, ERROR_NOT_FOUND if the info
* does not match, or the last error otherwise.
*/
DWORD
CheckCertificateForPEFile
(
LPCWSTR
filePath
,
CheckCertificateForPEFile
(
LPCWSTR
filePath
,
CertificateCheckInfo
&
infoToMatch
)
{
HCERTSTORE
certStore
=
nullptr
;
HCRYPTMSG
cryptMsg
=
nullptr
;
HCRYPTMSG
cryptMsg
=
nullptr
;
PCCERT_CONTEXT
certContext
=
nullptr
;
PCMSG_SIGNER_INFO
signerInfo
=
nullptr
;
DWORD
lastError
=
ERROR_SUCCESS
;
...
...
@@ -37,9 +37,9 @@ CheckCertificateForPEFile(LPCWSTR filePath,
// Get the HCERTSTORE and HCRYPTMSG from the signed file.
DWORD
encoding
,
contentType
,
formatType
;
BOOL
result
=
CryptQueryObject
(
CERT_QUERY_OBJECT_FILE
,
filePath
,
filePath
,
CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED
,
CERT_QUERY_CONTENT_FLAG_ALL
,
CERT_QUERY_CONTENT_FLAG_ALL
,
0
,
&
encoding
,
&
contentType
,
&
formatType
,
&
certStore
,
&
cryptMsg
,
nullptr
);
if
(
!
result
)
{
...
...
@@ -50,7 +50,7 @@ CheckCertificateForPEFile(LPCWSTR filePath,
// Pass in nullptr to get the needed signer information size.
DWORD
signerInfoSize
;
result
=
CryptMsgGetParam
(
cryptMsg
,
CMSG_SIGNER_INFO_PARAM
,
0
,
result
=
CryptMsgGetParam
(
cryptMsg
,
CMSG_SIGNER_INFO_PARAM
,
0
,
nullptr
,
&
signerInfoSize
);
if
(
!
result
)
{
lastError
=
GetLastError
();
...
...
@@ -68,7 +68,7 @@ CheckCertificateForPEFile(LPCWSTR filePath,
// Get the signer information (PCMSG_SIGNER_INFO).
// In particular we want the issuer and serial number.
result
=
CryptMsgGetParam
(
cryptMsg
,
CMSG_SIGNER_INFO_PARAM
,
0
,
result
=
CryptMsgGetParam
(
cryptMsg
,
CMSG_SIGNER_INFO_PARAM
,
0
,
(
PVOID
)
signerInfo
,
&
signerInfoSize
);
if
(
!
result
)
{
lastError
=
GetLastError
();
...
...
@@ -77,10 +77,10 @@ CheckCertificateForPEFile(LPCWSTR filePath,
}
// Search for the signer certificate in the certificate store.
CERT_INFO
certInfo
;
CERT_INFO
certInfo
;
certInfo
.
Issuer
=
signerInfo
->
Issuer
;
certInfo
.
SerialNumber
=
signerInfo
->
SerialNumber
;
certContext
=
CertFindCertificateInStore
(
certStore
,
ENCODING
,
0
,
certContext
=
CertFindCertificateInStore
(
certStore
,
ENCODING
,
0
,
CERT_FIND_SUBJECT_CERT
,
(
PVOID
)
&
certInfo
,
nullptr
);
if
(
!
certContext
)
{
...
...
@@ -102,10 +102,10 @@ cleanup:
if
(
certContext
)
{
CertFreeCertificateContext
(
certContext
);
}
if
(
certStore
)
{
if
(
certStore
)
{
CertCloseStore
(
certStore
,
0
);
}
if
(
cryptMsg
)
{
if
(
cryptMsg
)
{
CryptMsgClose
(
cryptMsg
);
}
return
lastError
;
...
...
@@ -118,8 +118,8 @@ cleanup:
* @param infoToMatch The acceptable information to match
* @return FALSE if the info does not match or if any error occurs in the check
*/
BOOL
DoCertificateAttributesMatch
(
PCCERT_CONTEXT
certContext
,
BOOL
DoCertificateAttributesMatch
(
PCCERT_CONTEXT
certContext
,
CertificateCheckInfo
&
infoToMatch
)
{
DWORD
dwData
;
...
...
@@ -127,7 +127,7 @@ DoCertificateAttributesMatch(PCCERT_CONTEXT certContext,
if
(
infoToMatch
.
issuer
)
{
// Pass in nullptr to get the needed size of the issuer buffer.
dwData
=
CertGetNameString
(
certContext
,
dwData
=
CertGetNameString
(
certContext
,
CERT_NAME_SIMPLE_DISPLAY_TYPE
,
CERT_NAME_ISSUER_FLAG
,
nullptr
,
nullptr
,
0
);
...
...
@@ -190,7 +190,7 @@ DoCertificateAttributesMatch(PCCERT_CONTEXT certContext,
}
// If the issuer does not match, return a failure.
if
(
!
infoToMatch
.
name
||
if
(
!
infoToMatch
.
name
||
wcscmp
(
szName
,
infoToMatch
.
name
))
{
LocalFree
(
szName
);
return
FALSE
;
...
...
@@ -210,10 +210,10 @@ DoCertificateAttributesMatch(PCCERT_CONTEXT certContext,
* @param inputString The string to duplicate
* @return The duplicated string which should be freed by the caller.
*/
LPWSTR
LPWSTR
AllocateAndCopyWideString
(
LPCWSTR
inputString
)
{
LPWSTR
outputString
=
LPWSTR
outputString
=
(
LPWSTR
)
LocalAlloc
(
LPTR
,
(
wcslen
(
inputString
)
+
1
)
*
sizeof
(
WCHAR
));
if
(
outputString
)
{
lstrcpyW
(
outputString
,
inputString
);
...
...
@@ -243,7 +243,7 @@ VerifyCertificateTrustForFile(LPCWSTR filePath)
trustData
.
pPolicyCallbackData
=
nullptr
;
trustData
.
pSIPClientData
=
nullptr
;
trustData
.
dwUIChoice
=
WTD_UI_NONE
;
trustData
.
fdwRevocationChecks
=
WTD_REVOKE_NONE
;
trustData
.
fdwRevocationChecks
=
WTD_REVOKE_NONE
;
trustData
.
dwUnionChoice
=
WTD_CHOICE_FILE
;
trustData
.
dwStateAction
=
0
;
trustData
.
hWVTStateData
=
nullptr
;
...
...
onlineupdate/source/service/maintenanceservice.cxx
Dosyayı görüntüle @
7eca4fa0
...
...
@@ -12,15 +12,15 @@
#include "maintenanceservice.hxx"
#include "servicebase.hxx"
#include "workmonitor.hxx"
#include "uachelper.h
xx
"
#include "updatehelper.h
xx
"
#include "uachelper.h"
#include "updatehelper.h"
// Link w/ subsystem window so we don't get a console when executing
// this binary through the installer.
#pragma comment(linker, "/SUBSYSTEM:windows")
SERVICE_STATUS
gSvcStatus
=
{
0
};
SERVICE_STATUS_HANDLE
gSvcStatusHandle
=
nullptr
;
SERVICE_STATUS
gSvcStatus
=
{
0
};
SERVICE_STATUS_HANDLE
gSvcStatusHandle
=
nullptr
;
HANDLE
gWorkDoneEvent
=
nullptr
;
HANDLE
gThread
=
nullptr
;
bool
gServiceControlStopping
=
false
;
...
...
@@ -30,9 +30,14 @@ bool gServiceControlStopping = false;
BOOL
GetLogDirectoryPath
(
WCHAR
*
path
);
int
int
wmain
(
int
argc
,
WCHAR
**
argv
)
{
if
(
argc
<
2
)
{
LOG_WARN
((
"missing mandatory command line argument"
));
return
1
;
}
// If command-line parameter is "install", install the service
// or upgrade if already installed
// If command line parameter is "forceinstall", install the service
...
...
@@ -66,7 +71,7 @@ wmain(int argc, WCHAR **argv)
LOG
((
"The service was installed successfully"
));
LogFinish
();
return
0
;
}
}
if
(
!
lstrcmpi
(
argv
[
1
],
L"upgrade"
))
{
WCHAR
updatePath
[
MAX_PATH
+
1
];
...
...
@@ -102,12 +107,12 @@ wmain(int argc, WCHAR **argv)
return
0
;
}
SERVICE_TABLE_ENTRYW
DispatchTable
[]
=
{
{
SVC_NAME
,
(
LPSERVICE_MAIN_FUNCTIONW
)
SvcMain
},
{
nullptr
,
nullptr
}
};
SERVICE_TABLE_ENTRYW
DispatchTable
[]
=
{
{
SVC_NAME
,
(
LPSERVICE_MAIN_FUNCTIONW
)
SvcMain
},
{
nullptr
,
nullptr
}
};
// This call returns when the service has stopped.
// This call returns when the service has stopped.
// The process should simply terminate when the call returns.
if
(
!
StartServiceCtrlDispatcherW
(
DispatchTable
))
{
LOG_WARN
((
"StartServiceCtrlDispatcher failed. (%d)"
,
GetLastError
()));
...
...
@@ -125,7 +130,7 @@ wmain(int argc, WCHAR **argv)
BOOL
GetLogDirectoryPath
(
WCHAR
*
path
)
{
HRESULT
hr
=
SHGetFolderPathW
(
nullptr
,
CSIDL_COMMON_APPDATA
,
nullptr
,
HRESULT
hr
=
SHGetFolderPathW
(
nullptr
,
CSIDL_COMMON_APPDATA
,
nullptr
,
SHGFP_TYPE_CURRENT
,
path
);
if
(
FAILED
(
hr
))
{
return
FALSE
;
...
...
@@ -175,7 +180,7 @@ GetBackupLogPath(LPWSTR path, LPCWSTR basePath, int logNumber)
* updater1.log -> updater2.log
* updater.log -> updater1.log
* Which clears room for a new updater.log in the basePath directory
*
*
* @param basePath The base directory path where log files are stored
* @param numLogsToKeep The number of logs to keep
*/
...
...
@@ -203,14 +208,14 @@ BackupOldLogs(LPCWSTR basePath, int numLogsToKeep)
* Ensures the service is shutdown once all work is complete.
* There is an issue on XP SP2 and below where the service can hang
* in a stop pending state even though the SCM is notified of a stopped
* state. Control *should* be returned to StartServiceCtrlDispatcher from the
* call to SetServiceStatus on a stopped state in the wmain thread.
* state. Control *should* be returned to StartServiceCtrlDispatcher from the
* call to SetServiceStatus on a stopped state in the wmain thread.
* Sometimes this is not the case though. This thread will terminate the process
* if it has been 5 seconds after all work is done and the process is still not
* terminated. This thread is only started once a stopped state was sent to the
* SCM. The stop pending hang can be reproduced intermittently even if you set
* a stopped state dirctly and never set a stop pending state. It is safe to
* forcefully terminate the process ourselves since all work is done once we
* SCM. The stop pending hang can be reproduced intermittently even if you set
* a stopped state dirctly and never set a stop pending state. It is safe to
* forcefully terminate the process ourselves since all work is done once we
* start this thread.
*/
DWORD
WINAPI
...
...
@@ -218,13 +223,12 @@ EnsureProcessTerminatedThread(LPVOID)
{
Sleep
(
5000
);
exit
(
0
);
return
0
;
}
void
StartTerminationThread
()
{
// If the process does not self terminate like it should, this thread
// If the process does not self terminate like it should, this thread
// will terminate the process after 5 seconds.
HANDLE
thread
=
CreateThread
(
nullptr
,
0
,
EnsureProcessTerminatedThread
,
nullptr
,
0
,
nullptr
);
...
...
@@ -254,10 +258,10 @@ SvcMain(DWORD argc, LPWSTR *argv)
gSvcStatusHandle
=
RegisterServiceCtrlHandlerW
(
SVC_NAME
,
SvcCtrlHandler
);
if
(
!
gSvcStatusHandle
)
{
LOG_WARN
((
"RegisterServiceCtrlHandler failed. (%d)"
,
GetLastError
()));
ExecuteServiceCommand
(
argc
,
argv
);
ExecuteServiceCommand
(
argc
,
argv
);
LogFinish
();
exit
(
1
);
}
}
// These values will be re-used later in calls involving gSvcStatus
gSvcStatus
.
dwServiceType
=
SERVICE_WIN32_OWN_PROCESS
;
...
...
@@ -282,7 +286,7 @@ SvcMain(DWORD argc, LPWSTR *argv)
// The service command was executed, stop logging and set an event
// to indicate the work is done in case someone is waiting on a
// service stop operation.
ExecuteServiceCommand
(
argc
,
argv
);
ExecuteServiceCommand
(
argc
,
argv
);
LogFinish
();
SetEvent
(
gWorkDoneEvent
);
...
...
@@ -298,14 +302,14 @@ SvcMain(DWORD argc, LPWSTR *argv)
/**
* Sets the current service status and reports it to the SCM.
*
*
* @param currentState The current state (see SERVICE_STATUS)
* @param exitCode The system error code
* @param waitHint Estimated time for pending operation in milliseconds
*/
void
ReportSvcStatus
(
DWORD
currentState
,
DWORD
exitCode
,
ReportSvcStatus
(
DWORD
currentState
,
DWORD
exitCode
,
DWORD
waitHint
)
{
static
DWORD
dwCheckPoint
=
1
;
...
...
@@ -314,11 +318,11 @@ ReportSvcStatus(DWORD currentState,
gSvcStatus
.
dwWin32ExitCode
=
exitCode
;
gSvcStatus
.
dwWaitHint
=
waitHint
;
if
(
SERVICE_START_PENDING
==
currentState
||
if
(
SERVICE_START_PENDING
==
currentState
||
SERVICE_STOP_PENDING
==
currentState
)
{
gSvcStatus
.
dwControlsAccepted
=
0
;
}
else
{
gSvcStatus
.
dwControlsAccepted
=
SERVICE_ACCEPT_STOP
|
gSvcStatus
.
dwControlsAccepted
=
SERVICE_ACCEPT_STOP
|
SERVICE_ACCEPT_SHUTDOWN
;
}
...
...
@@ -334,8 +338,8 @@ ReportSvcStatus(DWORD currentState,
}
/**
* Since the SvcCtrlHandler should only spend at most 30 seconds before
* returning, this function does the service stop work for the SvcCtrlHandler.
* Since the SvcCtrlHandler should only spend at most 30 seconds before
* returning, this function does the service stop work for the SvcCtrlHandler.
*/
DWORD
WINAPI
StopServiceAndWaitForCommandThread
(
LPVOID
)
...
...
@@ -363,15 +367,15 @@ SvcCtrlHandler(DWORD dwCtrl)
return
;
}
// Handle the requested control code.
// Handle the requested control code.
switch
(
dwCtrl
)
{
case
SERVICE_CONTROL_SHUTDOWN
:
case
SERVICE_CONTROL_STOP
:
{
gServiceControlStopping
=
true
;
ReportSvcStatus
(
SERVICE_STOP_PENDING
,
NO_ERROR
,
1000
);
// The SvcCtrlHandler thread should not spend more than 30 seconds in
// shutdown so we spawn a new thread for stopping the service
// The SvcCtrlHandler thread should not spend more than 30 seconds in
// shutdown so we spawn a new thread for stopping the service
HANDLE
thread
=
CreateThread
(
nullptr
,
0
,
StopServiceAndWaitForCommandThread
,
nullptr
,
0
,
nullptr
);
...
...
onlineupdate/source/service/registrycertificates.cxx
Dosyayı görüntüle @
7eca4fa0
...
...
@@ -6,13 +6,46 @@
#include <stdlib.h>
#include <windows.h>
#include <memory>
#include "registrycertificates.hxx"
#include "pathhash.hxx"
#include "nsWindowsHelpers.hxx"
#include "pathhash.h"
#include "servicebase.hxx"
#include "updatehelper.h
xx
"
#include "updatehelper.h"
#define MAX_KEY_LENGTH 255
namespace
{
struct
AutoRegKey
{
AutoRegKey
(
HKEY
key
)
:
mKey
(
key
)
{
}
~
AutoRegKey
()
{
releaseKey
(
mKey
);
}
void
releaseKey
(
HKEY
key
)
{
if
(
key
!=
nullptr
)
{
RegCloseKey
(
key
);
}
}
HKEY
mKey
;
HKEY
get
()
{
return
mKey
;
}
};
}
/**
* Verifies if the file path matches any certificate stored in the registry.
*
...
...
@@ -21,9 +54,9 @@
*/
BOOL
DoesBinaryMatchAllowedCertificates
(
LPCWSTR
basePathForUpdate
,
LPCWSTR
filePath
)
{
{
WCHAR
maintenanceServiceKey
[
MAX_PATH
+
1
];
if
(
!
CalculateRegistryPathFromFilePath
(
basePathForUpdate
,
if
(
!
CalculateRegistryPathFromFilePath
(
basePathForUpdate
,
maintenanceServiceKey
))
{
return
FALSE
;
}
...
...
@@ -35,15 +68,15 @@ DoesBinaryMatchAllowedCertificates(LPCWSTR basePathForUpdate, LPCWSTR filePath)
// force the non redirected registry under Wow6432Node.
// This flag is ignored on 32bit systems.
HKEY
baseKeyRaw
;
LONG
retCode
=
RegOpenKeyExW
(
HKEY_LOCAL_MACHINE
,
maintenanceServiceKey
,
0
,
LONG
retCode
=
RegOpenKeyExW
(
HKEY_LOCAL_MACHINE
,
maintenanceServiceKey
,
0
,
KEY_READ
|
KEY_WOW64_64KEY
,
&
baseKeyRaw
);
if
(
retCode
!=
ERROR_SUCCESS
)
{
LOG_WARN
((
"Could not open key. (%d)"
,
retCode
));
// Our tests run with a different apply directory for each test.
// We use this registry key on our test slaves to store the
// We use this registry key on our test slaves to store the
// allowed name/issuers.
retCode
=
RegOpenKeyExW
(
HKEY_LOCAL_MACHINE
,
retCode
=
RegOpenKeyExW
(
HKEY_LOCAL_MACHINE
,
TEST_ONLY_FALLBACK_KEY_PATH
,
0
,
KEY_READ
|
KEY_WOW64_64KEY
,
&
baseKeyRaw
);
if
(
retCode
!=
ERROR_SUCCESS
)
{
...
...
@@ -51,11 +84,11 @@ DoesBinaryMatchAllowedCertificates(LPCWSTR basePathForUpdate, LPCWSTR filePath)
return
FALSE
;
}
}
ns
AutoRegKey
baseKey
(
baseKeyRaw
);
AutoRegKey
baseKey
(
baseKeyRaw
);
// Get the number of subkeys.
DWORD
subkeyCount
=
0
;
retCode
=
RegQueryInfoKeyW
(
baseKey
,
nullptr
,
nullptr
,
nullptr
,
&
subkeyCount
,
retCode
=
RegQueryInfoKeyW
(
baseKey
.
get
()
,
nullptr
,
nullptr
,
nullptr
,
&
subkeyCount
,
nullptr
,
nullptr
,
nullptr
,
nullptr
,
nullptr
,
nullptr
,
nullptr
);
if
(
retCode
!=
ERROR_SUCCESS
)
{
...
...
@@ -64,12 +97,12 @@ DoesBinaryMatchAllowedCertificates(LPCWSTR basePathForUpdate, LPCWSTR filePath)
}
// Enumerate the subkeys, each subkey represents an allowed certificate.
for
(
DWORD
i
=
0
;
i
<
subkeyCount
;
i
++
)
{
for
(
DWORD
i
=
0
;
i
<
subkeyCount
;
i
++
)
{
WCHAR
subkeyBuffer
[
MAX_KEY_LENGTH
];
DWORD
subkeyBufferCount
=
MAX_KEY_LENGTH
;
retCode
=
RegEnumKeyExW
(
baseKey
,
i
,
subkeyBuffer
,
&
subkeyBufferCount
,
nullptr
,
nullptr
,
nullptr
,
nullptr
);
DWORD
subkeyBufferCount
=
MAX_KEY_LENGTH
;
retCode
=
RegEnumKeyExW
(
baseKey
.
get
(),
i
,
subkeyBuffer
,
&
subkeyBufferCount
,
nullptr
,
nullptr
,
nullptr
,
nullptr
);
if
(
retCode
!=
ERROR_SUCCESS
)
{
LOG_WARN
((
"Could not enum certs. (%d)"
,
retCode
));
return
FALSE
;
...
...
@@ -77,12 +110,12 @@ DoesBinaryMatchAllowedCertificates(LPCWSTR basePathForUpdate, LPCWSTR filePath)
// Open the subkey for the current certificate
HKEY
subKeyRaw
;
retCode
=
RegOpenKeyExW
(
baseKey
,
subkeyBuffer
,
0
,
KEY_READ
|
KEY_WOW64_64KEY
,
retCode
=
RegOpenKeyExW
(
baseKey
.
get
(),
subkeyBuffer
,
0
,
KEY_READ
|
KEY_WOW64_64KEY
,
&
subKeyRaw
);
ns
AutoRegKey
subKey
(
subKeyRaw
);
AutoRegKey
subKey
(
subKeyRaw
);
if
(
retCode
!=
ERROR_SUCCESS
)
{
LOG_WARN
((
"Could not open subkey. (%d)"
,
retCode
));
continue
;
// Try the next subkey
...
...
@@ -94,7 +127,7 @@ DoesBinaryMatchAllowedCertificates(LPCWSTR basePathForUpdate, LPCWSTR filePath)
WCHAR
issuer
[
MAX_CHAR_COUNT
]
=
{
L'\0'
};
// Get the name from the registry
retCode
=
RegQueryValueExW
(
subKey
,
L"name"
,
0
,
nullptr
,
retCode
=
RegQueryValueExW
(
subKey
.
get
(),
L"name"
,
0
,
nullptr
,
(
LPBYTE
)
name
,
&
valueBufSize
);
if
(
retCode
!=
ERROR_SUCCESS
)
{
LOG_WARN
((
"Could not obtain name from registry. (%d)"
,
retCode
));
...
...
@@ -103,7 +136,7 @@ DoesBinaryMatchAllowedCertificates(LPCWSTR basePathForUpdate, LPCWSTR filePath)
// Get the issuer from the registry
valueBufSize
=
MAX_CHAR_COUNT
*
sizeof
(
WCHAR
);
retCode
=
RegQueryValueExW
(
subKey
,
L"issuer"
,
0
,
nullptr
,
retCode
=
RegQueryValueExW
(
subKey
.
get
(),
L"issuer"
,
0
,
nullptr
,
(
LPBYTE
)
issuer
,
&
valueBufSize
);
if
(
retCode
!=
ERROR_SUCCESS
)
{
LOG_WARN
((
"Could not obtain issuer from registry. (%d)"
,
retCode
));
...
...
@@ -111,8 +144,8 @@ DoesBinaryMatchAllowedCertificates(LPCWSTR basePathForUpdate, LPCWSTR filePath)
}
CertificateCheckInfo
allowedCertificate
=
{
name
,
issuer
,
name
,
issuer
,
};
retCode
=
CheckCertificateForPEFile
(
filePath
,
allowedCertificate
);
...
...
@@ -128,9 +161,9 @@ DoesBinaryMatchAllowedCertificates(LPCWSTR basePathForUpdate, LPCWSTR filePath)
}
// Raise the roof, we found a match!
return
TRUE
;
return
TRUE
;
}
// No certificates match, :'(
return
FALSE
;
}
onlineupdate/source/service/servicebase.cxx
Dosyayı görüntüle @
7eca4fa0
...
...
@@ -3,10 +3,9 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "servicebase.hxx"
#include "
nsWindowsHelpers
.hxx"
#include "
windowsHelper
.hxx"
// Shared code between applications and updater.exe
#include "nsWindowsRestart.cpp"
/**
* Verifies if 2 files are byte for byte equivalent.
...
...
@@ -20,19 +19,19 @@ BOOL
VerifySameFiles
(
LPCWSTR
file1Path
,
LPCWSTR
file2Path
,
BOOL
&
sameContent
)
{
sameContent
=
FALSE
;
nsAutoHandle
file1
(
CreateFileW
(
file1Path
,
GENERIC_READ
,
FILE_SHARE_READ
,
AutoHandle
file1
(
CreateFileW
(
file1Path
,
GENERIC_READ
,
FILE_SHARE_READ
,
nullptr
,
OPEN_EXISTING
,
0
,
nullptr
));
if
(
INVALID_HANDLE_VALUE
==
file1
)
{
if
(
file1
==
INVALID_HANDLE_VALUE
)
{
return
FALSE
;
}
nsAutoHandle
file2
(
CreateFileW
(
file2Path
,
GENERIC_READ
,
FILE_SHARE_READ
,
AutoHandle
file2
(
CreateFileW
(
file2Path
,
GENERIC_READ
,
FILE_SHARE_READ
,
nullptr
,
OPEN_EXISTING
,
0
,
nullptr
));
if
(
INVALID_HANDLE_VALUE
==
file2
)
{
if
(
file2
==
INVALID_HANDLE_VALUE
)
{
return
FALSE
;
}
DWORD
fileSize1
=
GetFileSize
(
file1
,
nullptr
);
DWORD
fileSize2
=
GetFileSize
(
file2
,
nullptr
);
DWORD
fileSize1
=
GetFileSize
(
file1
.
get
()
,
nullptr
);
DWORD
fileSize2
=
GetFileSize
(
file2
.
get
()
,
nullptr
);
if
(
INVALID_FILE_SIZE
==
fileSize1
||
INVALID_FILE_SIZE
==
fileSize2
)
{
return
FALSE
;
}
...
...
@@ -48,12 +47,12 @@ VerifySameFiles(LPCWSTR file1Path, LPCWSTR file2Path, BOOL &sameContent)
DWORD
leftOver
=
fileSize1
%
COMPARE_BLOCKSIZE
;
DWORD
readAmount
;
for
(
DWORD
i
=
0
;
i
<
numBlocks
;
i
++
)
{
if
(
!
ReadFile
(
file1
,
buf1
,
COMPARE_BLOCKSIZE
,
&
readAmount
,
nullptr
)
||
if
(
!
ReadFile
(
file1
.
get
()
,
buf1
,
COMPARE_BLOCKSIZE
,
&
readAmount
,
nullptr
)
||
readAmount
!=
COMPARE_BLOCKSIZE
)
{
return
FALSE
;
}
if
(
!
ReadFile
(
file2
,
buf2
,
COMPARE_BLOCKSIZE
,
&
readAmount
,
nullptr
)
||
if
(
!
ReadFile
(
file2
.
get
()
,
buf2
,
COMPARE_BLOCKSIZE
,
&
readAmount
,
nullptr
)
||
readAmount
!=
COMPARE_BLOCKSIZE
)
{
return
FALSE
;
}
...
...
@@ -65,12 +64,12 @@ VerifySameFiles(LPCWSTR file1Path, LPCWSTR file2Path, BOOL &sameContent)
}
if
(
leftOver
)
{
if
(
!
ReadFile
(
file1
,
buf1
,
leftOver
,
&
readAmount
,
nullptr
)
||
if
(
!
ReadFile
(
file1
.
get
()
,
buf1
,
leftOver
,
&
readAmount
,
nullptr
)
||
readAmount
!=
leftOver
)
{
return
FALSE
;
}
if
(
!
ReadFile
(
file2
,
buf2
,
leftOver
,
&
readAmount
,
nullptr
)
||
if
(
!
ReadFile
(
file2
.
get
()
,
buf2
,
leftOver
,
&
readAmount
,
nullptr
)
||
readAmount
!=
leftOver
)
{
return
FALSE
;
}
...
...
onlineupdate/source/service/servicebase.hxx
Dosyayı görüntüle @
7eca4fa0
...
...
@@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <windows.h>
#include "updatelogging.h
xx
"
#include "updatelogging.h"
BOOL
PathAppendSafe
(
LPWSTR
base
,
LPCWSTR
extra
);
BOOL
VerifySameFiles
(
LPCWSTR
file1Path
,
LPCWSTR
file2Path
,
BOOL
&
sameContent
);
...
...
onlineupdate/source/service/serviceinstall.cxx
Dosyayı görüntüle @
7eca4fa0
This diff is collapsed.
Click to expand it.
onlineupdate/source/service/windowsHelper.hxx
0 → 100644
Dosyayı görüntüle @
7eca4fa0
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#ifndef INCLUDED_ONLINEUPDATE_SERVICE_WINDOWSHELPER_HXX
#define INCLUDED_ONLINEUPDATE_SERVICE_WINDOWSHELPER_HXX
struct
AutoHandle
{
AutoHandle
(
HANDLE
handle
)
:
mHandle
(
handle
)
{
}
~
AutoHandle
()
{
release
(
mHandle
);
}
void
release
(
HANDLE
handle
)
{
if
(
handle
&&
handle
!=
INVALID_HANDLE_VALUE
)
{
CloseHandle
(
handle
);
}
}
HANDLE
get
()
const
{
return
mHandle
;
}
bool
operator
==
(
const
AutoHandle
&
rhs
)
{
return
mHandle
==
rhs
.
mHandle
;
}
HANDLE
mHandle
;
};
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
onlineupdate/source/service/workmonitor.cxx
Dosyayı görüntüle @
7eca4fa0
...
...
@@ -7,6 +7,7 @@
#include <wtsapi32.h>
#include <userenv.h>
#include <shellapi.h>
#include <cstddef>
#pragma comment(lib, "wtsapi32.lib")
#pragma comment(lib, "userenv.lib")
...
...
@@ -14,23 +15,22 @@
#pragma comment(lib, "ole32.lib")
#pragma comment(lib, "rpcrt4.lib")
#include "nsWindowsHelpers.h"
#include "workmonitor.h"
#include "serviceinstall.h"
#include "servicebase.h"
#include "registrycertificates.h"
#include "workmonitor.hxx"
#include "serviceinstall.hxx"
#include "servicebase.hxx"
#include "registrycertificates.hxx"
#include "uachelper.h"
#include "updatehelper.h"
#include "errors.h"
#include "windowsHelper.hxx"
// Wait 15 minutes for an update operation to run at most.
// Updates usually take less than a minute so this seems like a
// significantly large and safe amount of time to wait.
static
const
int
TIME_TO_WAIT_ON_UPDATER
=
15
*
60
*
1000
;
char16_t
*
MakeCommandLine
(
int
argc
,
char16
_t
**
argv
);
wchar_t
*
MakeCommandLine
(
int
argc
,
wchar
_t
**
argv
);
BOOL
WriteStatusFailure
(
LPCWSTR
updateDirPath
,
int
errorCode
);
BOOL
PathGetSiblingFilePath
(
LPWSTR
destinationBuffer
,
LPCWSTR
siblingFilePath
,
BOOL
PathGetSiblingFilePath
(
LPWSTR
destinationBuffer
,
LPCWSTR
siblingFilePath
,
LPCWSTR
newFileName
);
/*
...
...
@@ -53,20 +53,20 @@ IsStatusApplying(LPCWSTR updateDirPath, BOOL &isApplying)
return
FALSE
;
}
ns
AutoHandle
statusFile
(
CreateFileW
(
updateStatusFilePath
,
GENERIC_READ
,
AutoHandle
statusFile
(
CreateFileW
(
updateStatusFilePath
,
GENERIC_READ
,
FILE_SHARE_READ
|
FILE_SHARE_WRITE
|
FILE_SHARE_DELETE
,
nullptr
,
OPEN_EXISTING
,
0
,
nullptr
));
if
(
INVALID_HANDLE_VALUE
==
statusFile
)
{
if
(
statusFile
==
INVALID_HANDLE_VALUE
)
{
LOG_WARN
((
"Could not open update.status file"
));
return
FALSE
;
}
char
buf
[
32
]
=
{
0
};
DWORD
read
;
if
(
!
ReadFile
(
statusFile
,
buf
,
sizeof
(
buf
),
&
read
,
nullptr
))
{
if
(
!
ReadFile
(
statusFile
.
get
()
,
buf
,
sizeof
(
buf
),
&
read
,
nullptr
))
{
LOG_WARN
((
"Could not read from update.status file"
));
return
FALSE
;
}
...
...
@@ -378,9 +378,9 @@ ProcessSoftwareUpdateCommand(DWORD argc, LPWSTR *argv)
return
FALSE
;
}
ns
AutoHandle
noWriteLock
(
CreateFileW
(
argv
[
0
],
GENERIC_READ
,
FILE_SHARE_READ
,
AutoHandle
noWriteLock
(
CreateFileW
(
argv
[
0
],
GENERIC_READ
,
FILE_SHARE_READ
,
nullptr
,
OPEN_EXISTING
,
0
,
nullptr
));
if
(
INVALID_HANDLE_VALUE
==
noWriteLock
)
{
if
(
noWriteLock
==
INVALID_HANDLE_VALUE
)
{
LOG_WARN
((
"Could not set no write sharing access on file. (%d)"
,
GetLastError
()));
if
(
!
WriteStatusFailure
(
argv
[
1
],
...
...
@@ -401,7 +401,7 @@ ProcessSoftwareUpdateCommand(DWORD argc, LPWSTR *argv)
result
=
FALSE
;
}
BOOL
updaterIsCorrect
;
BOOL
updaterIsCorrect
=
FALSE
;
if
(
result
&&
!
VerifySameFiles
(
argv
[
0
],
installDirUpdater
,
updaterIsCorrect
))
{
LOG_WARN
((
"Error checking if the updaters are the same.
\n
"
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment