bug 458950 - updater doesn't build for windows CE r=vlad,bsmedberg

This commit is contained in:
Brad Lassey 2009-07-16 18:21:09 -04:00
parent bd5116b7fb
commit 0d477d785b
8 changed files with 328 additions and 69 deletions

View File

@ -81,6 +81,14 @@ endif
REQUIRES += string
endif
ifeq ($(OS_ARCH),WINCE)
USE_STATIC_LIBS = 1
OS_LIBS += $(call EXPAND_LIBNAME,ws2)
DEFINES += -DUNICODE -D_UNICODE
RCFLAGS += -I$(srcdir)
REQUIRES += string
endif
ifneq ($(MOZ_ENABLE_GTK2),)
HAVE_PROGRESSUI = 1
CPPSRCS += \
@ -108,6 +116,10 @@ MOZ_WINCONSOLE = 0
endif
endif
ifeq ($(OS_ARCH), WINCE)
CPPSRCS += updater_wince.cpp
endif
include $(topsrcdir)/config/rules.mk
DEFINES += -DNS_NO_XPCOM
@ -137,7 +149,7 @@ libs::
rm -f $(DIST)/bin/updater
endif
ifeq ($(OS_ARCH),WINNT)
ifeq (,$(filter-out WINCE WINNT,$(OS_ARCH)))
# Pick up nsWindowsRestart.cpp
LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/xre
endif

View File

@ -48,6 +48,10 @@
# include <io.h>
#endif
#ifdef WINCE
#include "updater_wince.h"
#endif
int
#ifdef XP_WIN
ArchiveReader::Open(const WCHAR *path)
@ -86,14 +90,14 @@ ArchiveReader::ExtractFile(const char *name, const char *dest)
return READ_ERROR;
#ifdef XP_WIN
int fd = _open(dest, _O_BINARY|_O_CREAT|_O_TRUNC|_O_WRONLY, item->flags);
FILE* fp = fopen(dest, "wb+");
#else
int fd = creat(dest, item->flags);
#endif
if (fd == -1)
return WRITE_ERROR;
FILE *fp = fdopen(fd, "wb");
#endif
if (!fp)
return WRITE_ERROR;

View File

@ -55,10 +55,14 @@
# define SSIZE_MAX LONG_MAX
#endif
#ifdef WINCE
#include "updater_wince.h"
#endif
int
MBS_ReadHeader(int fd, MBSPatchHeader *header)
MBS_ReadHeader(FILE* file, MBSPatchHeader *header)
{
int s = read(fd, header, sizeof(MBSPatchHeader));
int s = fread(header, 1, sizeof(MBSPatchHeader), file);
if (s != sizeof(MBSPatchHeader))
return READ_ERROR;
@ -70,7 +74,7 @@ MBS_ReadHeader(int fd, MBSPatchHeader *header)
header->extralen = ntohl(header->extralen);
struct stat hs;
s = fstat(fd, &hs);
s = fstat(fileno(file), &hs);
if (s)
return READ_ERROR;
@ -87,8 +91,8 @@ MBS_ReadHeader(int fd, MBSPatchHeader *header)
}
int
MBS_ApplyPatch(const MBSPatchHeader *header, int patchfd,
unsigned char *fbuffer, int filefd)
MBS_ApplyPatch(const MBSPatchHeader *header, FILE* patchFile,
unsigned char *fbuffer, FILE* file)
{
unsigned char *fbufend = fbuffer + header->slen;
@ -103,7 +107,7 @@ MBS_ApplyPatch(const MBSPatchHeader *header, int patchfd,
int r = header->cblen + header->difflen + header->extralen;
unsigned char *wb = buf;
while (r) {
int c = read(patchfd, wb, (r > SSIZE_MAX) ? SSIZE_MAX : r);
int c = fread(wb, 1, (r > SSIZE_MAX) ? SSIZE_MAX : r, patchFile);
if (c < 0) {
rv = READ_ERROR;
goto end;
@ -151,7 +155,7 @@ MBS_ApplyPatch(const MBSPatchHeader *header, int patchfd,
for (PRUint32 i = 0; i < ctrlsrc->x; ++i) {
diffsrc[i] += fbuffer[i];
}
if ((PRUint32) write(filefd, diffsrc, ctrlsrc->x) != ctrlsrc->x) {
if ((PRUint32) fwrite(diffsrc, 1, ctrlsrc->x, file) != ctrlsrc->x) {
rv = WRITE_ERROR;
goto end;
}
@ -164,7 +168,7 @@ MBS_ApplyPatch(const MBSPatchHeader *header, int patchfd,
rv = UNEXPECTED_ERROR;
goto end;
}
if ((PRUint32) write(filefd, extrasrc, ctrlsrc->y) != ctrlsrc->y) {
if ((PRUint32) fwrite(extrasrc, 1, ctrlsrc->y, file) != ctrlsrc->y) {
rv = WRITE_ERROR;
goto end;
}

View File

@ -34,6 +34,7 @@
// We use the NSPR types, but we don't link with NSPR
#include "prtypes.h"
#include <stdio.h>
typedef struct MBSPatchHeader_ {
/* "MBDIFF10" */
@ -68,7 +69,7 @@ typedef struct MBSPatchHeader_ {
* @param fd Must have been opened for reading, and be at the beginning
* of the file.
*/
int MBS_ReadHeader(int fd, MBSPatchHeader *header);
int MBS_ReadHeader(FILE* file, MBSPatchHeader *header);
/**
* Apply a patch. This method does not validate the checksum of the original
@ -81,8 +82,8 @@ int MBS_ReadHeader(int fd, MBSPatchHeader *header);
* to header->dlen if it is an existing file. The offset
* should be at the beginning of the file.
*/
int MBS_ApplyPatch(const MBSPatchHeader *header, int patchfd,
unsigned char *fbuffer, int filefd);
int MBS_ApplyPatch(const MBSPatchHeader *header, FILE* patchFile,
unsigned char *fbuffer, FILE* file);
typedef struct MBSPatchTriple_ {
PRUint32 x; /* add x bytes from oldfile to x bytes from the diff block */

View File

@ -40,7 +40,7 @@
#define PROGRESSUI_H__
#if defined(XP_WIN)
typedef WCHAR NS_tchar;
typedef unsigned short NS_tchar;
#define NS_main wmain
#else
typedef char NS_tchar;

View File

@ -66,7 +66,6 @@
# define NS_tstrrchr wcsrchr
# define NS_tchdir _wchdir
# define NS_tremove _wremove
# define NS_topen _wopen
# define NS_tfopen _wfopen
# define NS_tatoi _wtoi64
#else
@ -78,7 +77,6 @@
# define NS_tstrrchr strrchr
# define NS_tchdir chdir
# define NS_tremove remove
# define NS_topen open
# define NS_tfopen fopen
# define NS_tatoi atoi
#endif
@ -100,6 +98,10 @@
#include <limits.h>
#include <errno.h>
#ifdef WINCE
#include "updater_wince.h"
#endif
#if defined(XP_MACOSX)
// This function is defined in launchchild_osx.mm
void LaunchChild(int argc, char **argv);
@ -164,33 +166,33 @@ crc32(const unsigned char *buf, unsigned int len)
//-----------------------------------------------------------------------------
// A simple stack based container for a file descriptor (int) that closes the
// A simple stack based container for a FILE struct that closes the
// file descriptor from its destructor.
class AutoFD
class AutoFile
{
public:
AutoFD(int fd = -1)
: mFD(fd) {
AutoFile(FILE* file = NULL)
: mFile(file) {
}
~AutoFD() {
if (mFD != -1)
close(mFD);
~AutoFile() {
if (mFile != NULL)
fclose(mFile);
}
AutoFD &operator=(int fd) {
if (mFD != -1)
close(mFD);
mFD = fd;
AutoFile &operator=(FILE* file) {
if (mFile != 0)
fclose(mFile);
mFile = file;
return *this;
}
operator int() {
return mFD;
operator FILE*() {
return mFile;
}
private:
int mFD;
FILE* mFile;
};
//-----------------------------------------------------------------------------
@ -208,7 +210,11 @@ public:
mThreadFunc = func;
mThreadParam = param;
unsigned threadID;
#ifdef WINCE
DWORD threadID;
#else
unsigned int threadID;
#endif
mThread = (HANDLE) _beginthreadex(NULL, 0, ThreadMain, this, 0, &threadID);
return mThread ? 0 : -1;
@ -403,10 +409,10 @@ static int ensure_remove(const char *path)
return rv;
}
static int ensure_open(const char *path, int flags, int options)
static FILE* ensure_open(const char *path, char* flags)
{
ensure_write_permissions(path);
return open(path, flags, options);
return fopen(path, flags);
}
// Ensure that the directory containing this file exists.
@ -441,24 +447,24 @@ static int copy_file(const char *spath, const char *dpath)
struct stat ss;
AutoFD sfd = open(spath, O_RDONLY | _O_BINARY);
if (sfd < 0 || fstat(sfd, &ss)) {
LOG(("copy_file: failed to open or stat: %d,%s,%d\n", (int) sfd, spath, errno));
AutoFile sfile = fopen(spath, "rb");
if (sfile == NULL || fstat(fileno(sfile), &ss)) {
LOG(("copy_file: failed to open or stat: %p,%s,%d\n", sfile, spath, errno));
return READ_ERROR;
}
AutoFD dfd = ensure_open(dpath, O_WRONLY | O_TRUNC | O_CREAT | _O_BINARY, ss.st_mode);
if (dfd < 0) {
AutoFile dfile = ensure_open(dpath, "wb+");
if (dfile == NULL) {
LOG(("copy_file: failed to open: %s,%d\n", dpath, errno));
return WRITE_ERROR;
}
char buf[BUFSIZ];
int sc;
while ((sc = read(sfd, buf, sizeof(buf))) > 0) {
while ((sc = fread(buf, 1, sizeof(buf), sfile)) > 0) {
int dc;
char *bp = buf;
while ((dc = write(dfd, bp, (unsigned int) sc)) > 0) {
while ((dc = fwrite(bp, 1, (unsigned int) sc, dfile)) > 0) {
if ((sc -= dc) == 0)
break;
bp += dc;
@ -738,7 +744,7 @@ AddFile::Finish(int status)
class PatchFile : public Action
{
public:
PatchFile() : mPatchIndex(-1), pfd(-1), buf(NULL) { }
PatchFile() : mPatchIndex(-1), pfile(NULL), buf(NULL) { }
virtual ~PatchFile();
virtual int Parse(char *line);
@ -747,7 +753,7 @@ public:
virtual void Finish(int status);
private:
int LoadSourceFile(int ofd);
int LoadSourceFile(FILE* ofile);
static int sPatchIndex;
@ -755,7 +761,7 @@ private:
const char *mFile;
int mPatchIndex;
MBSPatchHeader header;
int pfd;
FILE* pfile;
unsigned char *buf;
};
@ -763,8 +769,8 @@ int PatchFile::sPatchIndex = 0;
PatchFile::~PatchFile()
{
if (pfd >= 0)
close(pfd);
if (pfile)
fclose(pfile);
// delete the temporary patch file
NS_tchar spath[MAXPATHLEN];
@ -777,10 +783,10 @@ PatchFile::~PatchFile()
}
int
PatchFile::LoadSourceFile(int ofd)
PatchFile::LoadSourceFile(FILE* ofile)
{
struct stat os;
int rv = fstat(ofd, &os);
int rv = fstat(fileno(ofile), &os);
if (rv)
return READ_ERROR;
@ -794,7 +800,7 @@ PatchFile::LoadSourceFile(int ofd)
int r = header.slen;
unsigned char *rb = buf;
while (r) {
int c = read(ofd, rb, mmin(BUFSIZ,r));
int c = fread(rb, 1, mmin(BUFSIZ,r), ofile);
if (c < 0)
return READ_ERROR;
@ -865,19 +871,19 @@ PatchFile::Prepare()
// no need to open all of the patch files and read all of
// the source files before applying any patches.
pfd = NS_topen(spath, O_RDONLY | _O_BINARY);
if (pfd < 0)
pfile = NS_tfopen(spath, NS_T("rb"));
if (pfile == NULL)
return READ_ERROR;
rv = MBS_ReadHeader(pfd, &header);
rv = MBS_ReadHeader(pfile, &header);
if (rv)
return rv;
AutoFD ofd = open(mFile, O_RDONLY | _O_BINARY);
if (ofd < 0)
AutoFile ofile = fopen(mFile, "rb");
if (ofile == NULL)
return READ_ERROR;
rv = LoadSourceFile(ofd);
rv = LoadSourceFile(ofile);
if (rv)
LOG(("LoadSourceFile failed\n"));
return rv;
@ -902,11 +908,11 @@ PatchFile::Execute()
if (rv)
return WRITE_ERROR;
AutoFD ofd = ensure_open(mFile, O_WRONLY | O_TRUNC | O_CREAT | _O_BINARY, ss.st_mode);
if (ofd < 0)
AutoFile ofile = ensure_open(mFile, "wb+");
if (ofile == NULL)
return WRITE_ERROR;
return MBS_ApplyPatch(&header, pfd, buf, ofd);
return MBS_ApplyPatch(&header, pfile, buf, ofile);
}
void
@ -1071,7 +1077,9 @@ LaunchWinPostProcess(const WCHAR *appExe)
WCHAR exearg[MAXPATHLEN];
WCHAR exeasync[10];
PRBool async = PR_TRUE;
#ifdef WINCE
//XXX We will want this eventually, perhaps using nsINIParser
#else
if (!GetPrivateProfileStringW(L"PostUpdateWin", L"ExeRelPath", NULL, exefile,
MAXPATHLEN, inifile))
return;
@ -1083,6 +1091,7 @@ LaunchWinPostProcess(const WCHAR *appExe)
if (!GetPrivateProfileStringW(L"PostUpdateWin", L"ExeAsync", L"TRUE", exeasync,
sizeof(exeasync)/sizeof(exeasync[0]), inifile))
return;
#endif
WCHAR exefullpath[MAXPATHLEN];
wcscpy(exefullpath, appExe);
@ -1172,8 +1181,8 @@ WriteStatusFile(int status)
NS_tchar filename[MAXPATHLEN];
NS_tsnprintf(filename, MAXPATHLEN, NS_T("%s/update.status"), gSourcePath);
AutoFD fd = NS_topen(filename, O_WRONLY | O_TRUNC | O_CREAT | _O_BINARY, 0644);
if (fd < 0)
AutoFile file = NS_tfopen(filename, NS_T("wb+"));
if (file == NULL)
return;
const char *text;
@ -1185,7 +1194,7 @@ WriteStatusFile(int status)
snprintf(buf, sizeof(buf), "failed: %d\n", status);
text = buf;
}
write(fd, text, strlen(text));
fwrite(text, strlen(text), 1, file);
}
static void
@ -1214,8 +1223,9 @@ UpdateThreadFunc(void *param)
int NS_main(int argc, NS_tchar **argv)
{
#ifndef WINCE
InitProgressUI(&argc, &argv);
#endif
// The updater command line consists of the directory path containing the
// updater.mar file to process followed by the PID of the calling process.
// The updater will wait on the parent process to exit if the PID is non-
@ -1312,8 +1322,10 @@ int NS_main(int argc, NS_tchar **argv)
SHELLEXECUTEINFO sinfo;
memset(&sinfo, 0, sizeof(SHELLEXECUTEINFO));
sinfo.cbSize = sizeof(SHELLEXECUTEINFO);
sinfo.fMask = SEE_MASK_FLAG_DDEWAIT |
SEE_MASK_FLAG_NO_UI |
sinfo.fMask = SEE_MASK_FLAG_NO_UI |
#ifndef WINCE
SEE_MASK_FLAG_DDEWAIT |
#endif
SEE_MASK_NOCLOSEPROCESS;
sinfo.hwnd = NULL;
sinfo.lpFile = argv[0];
@ -1494,12 +1506,12 @@ int DoUpdate()
if (rv)
return rv;
AutoFD mfd = NS_topen(manifest, O_RDONLY | _O_BINARY);
if (mfd < 0)
AutoFile mfile = NS_tfopen(manifest, NS_T("rb"));
if (mfile == NULL)
return READ_ERROR;
struct stat ms;
rv = fstat(mfd, &ms);
rv = fstat(fileno(mfile), &ms);
if (rv)
return READ_ERROR;
@ -1510,7 +1522,7 @@ int DoUpdate()
int r = ms.st_size;
char *rb = mbuf;
while (r) {
int c = read(mfd, rb, mmin(SSIZE_MAX,r));
int c = fread(rb, 1, mmin(SSIZE_MAX,r), mfile);
if (c < 0)
return READ_ERROR;

View File

@ -0,0 +1,160 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Application Update..
*
* The Initial Developer of the Original Code is
* Brad Lassey <blassey@mozilla.com>.
*
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <windows.h>
#include "updater_wince.h"
# define F_OK 00
# define W_OK 02
# define R_OK 04
int remove(const char* path)
{
if (!_unlink(path)) {
return 0;
}
else if (GetLastError() == ERROR_ACCESS_DENIED) {
WCHAR wpath[MAX_PATH];
MultiByteToWideChar(CP_ACP,
0,
path,
-1,
wpath,
MAX_PATH );
return RemoveDirectoryW(wpath) ? 0:-1;
}
else {
return -1;
}
}
int chmod(const char* path, unsigned int mode)
{
return 0;
}
int fstat(FILE* handle, struct stat* buff)
{
int position = ftell(handle);
if (position < 0)
return -1;
if (fseek(handle, 0, SEEK_END) < 0)
return -1;
buff->st_size = ftell(handle);
if (fseek(handle, position, SEEK_SET) < 0)
return -1;
if (buff->st_size < 0)
return -1;
buff->st_mode = _S_IFREG | _S_IREAD | _S_IWRITE | _S_IEXEC;
/* can't get time from a file handle on wince */
buff->st_ctime = 0;
buff->st_atime = 0;
buff->st_mtime = 0;
return 0;
}
int stat(const char* path, struct stat* buf)
{
FILE* f = fopen(path, "r");
int rv = fstat(f, buf);
fclose(f);
return rv;
}
int _mkdir(const char* path)
{
WCHAR wpath[MAX_PATH];
MultiByteToWideChar(CP_ACP,
0,
path,
-1,
wpath,
MAX_PATH );
return CreateDirectoryW(wpath, NULL) ? 0 : -1;
}
FILE* fileno(FILE* f)
{
return f;
}
int _access(const char* path, int amode)
{
WCHAR wpath[MAX_PATH];
MultiByteToWideChar(CP_ACP,
0,
path,
-1,
wpath,
MAX_PATH );
switch (amode) {
case R_OK:
return (GetFileAttributesW(wpath) != INVALID_FILE_ATTRIBUTES);
default:
return 0;
}
}
int _waccess(const WCHAR* path, int amode)
{
switch (amode) {
case R_OK:
return (GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES);
default:
return 0;
}
}
int _wremove(const WCHAR* wpath)
{
if (DeleteFileW(wpath))
{
return 0;
}
else if (GetLastError() == ERROR_ACCESS_DENIED) {
return RemoveDirectoryW(wpath) ? 0:-1;
}
else {
return -1;
}
}

View File

@ -0,0 +1,66 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Application Update..
*
* The Initial Developer of the Original Code is
* Brad Lassey <blassey@mozilla.com>.
*
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef UPDATER_WINCE_H
#define UPDATER_WINCE_H
#define _S_IFDIR 0040000 /* stat, is a directory */
#define _S_IFREG 0100000 /* stat, is a normal file */
#define _S_IREAD 0000400 /* stat, can read */
#define _S_IWRITE 0000200 /* stat, can write */
#define _S_IEXEC 0000100
#define BUFSIZ 1024
#define _putenv putenv
struct stat {
unsigned short st_mode;
size_t st_size;
time_t st_ctime;
time_t st_atime;
time_t st_mtime;
};
int remove(const char* path);
int chmod(const char* path, unsigned int mode);
int fstat(FILE* handle, struct stat* buff);
int stat(const char* path, struct stat* buf);
int _mkdir(const char* path);
int access(const char* path, int amode);
int _waccess(const WCHAR* path, int amode);
int _wremove(const WCHAR* wpath);
#endif