LCOV - code coverage report
Current view: directory - toolkit/mozapps/update/test - TestAUSHelper.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 59 48 81.4 %
Date: 2012-06-02 Functions: 3 3 100.0 %

       1                 : /* Any copyright is dedicated to the Public Domain.
       2                 :  * http://creativecommons.org/publicdomain/zero/1.0/
       3                 :  */
       4                 : 
       5                 : #ifdef XP_WIN
       6                 : #pragma comment(lib, "wintrust.lib")
       7                 : #pragma comment(lib, "crypt32.lib")
       8                 : # include <windows.h>
       9                 : # include <wintrust.h>
      10                 : # include <tlhelp32.h>
      11                 : # include <softpub.h>
      12                 : # include <direct.h>
      13                 : # include <io.h>
      14                 :   typedef WCHAR NS_tchar;
      15                 : # define NS_main wmain
      16                 : # define F_OK 00
      17                 : # define W_OK 02
      18                 : # define R_OK 04
      19                 : # define stat _stat
      20                 : # define NS_T(str) L ## str
      21                 : # define NS_tsnprintf(dest, count, fmt, ...) \
      22                 :   { \
      23                 :     int _count = count - 1; \
      24                 :     _snwprintf(dest, _count, fmt, ##__VA_ARGS__); \
      25                 :     dest[_count] = L'\0'; \
      26                 :   }
      27                 : # define NS_taccess _waccess
      28                 : # define NS_tchdir _wchdir
      29                 : # define NS_tfopen _wfopen
      30                 : # define NS_tstrcmp wcscmp
      31                 : # define NS_ttoi _wtoi
      32                 : # define NS_tstat _wstat
      33                 : # define LOG_S "%S"
      34                 : 
      35                 : #include "../common/updatehelper.h"
      36                 : 
      37                 : #else
      38                 : # include <unistd.h>
      39                 : # define NS_main main
      40                 :   typedef char NS_tchar;
      41                 : # define NS_T(str) str
      42                 : # define NS_tsnprintf snprintf
      43                 : # define NS_taccess access
      44                 : # define NS_tchdir chdir
      45                 : # define NS_tfopen fopen
      46                 : # define NS_tstrcmp strcmp
      47                 : # define NS_ttoi atoi
      48                 : # define NS_tstat stat
      49                 : # define LOG_S "%s"
      50                 : #endif
      51                 : 
      52                 : #include <stdlib.h>
      53                 : #include <stdio.h>
      54                 : #include <string.h>
      55                 : #include <sys/types.h>
      56                 : #include <sys/stat.h>
      57                 : 
      58                 : #ifndef MAXPATHLEN
      59                 : # ifdef PATH_MAX
      60                 : #  define MAXPATHLEN PATH_MAX
      61                 : # elif defined(MAX_PATH)
      62                 : #  define MAXPATHLEN MAX_PATH
      63                 : # elif defined(_MAX_PATH)
      64                 : #  define MAXPATHLEN _MAX_PATH
      65                 : # elif defined(CCHMAXPATH)
      66                 : #  define MAXPATHLEN CCHMAXPATH
      67                 : # else
      68                 : #  define MAXPATHLEN 1024
      69                 : # endif
      70                 : #endif
      71                 : 
      72                 : static void
      73               2 : WriteMsg(const NS_tchar *path, const char *status)
      74                 : {
      75               2 :   FILE* outFP = NS_tfopen(path, NS_T("wb"));
      76               2 :   if (!outFP)
      77               0 :     return;
      78                 : 
      79               2 :   fprintf(outFP, "%s\n", status);
      80               2 :   fclose(outFP);
      81               2 :   outFP = NULL;
      82                 : }
      83                 : 
      84                 : static bool
      85               2 : CheckMsg(const NS_tchar *path, const char *expected)
      86                 : {
      87               2 :   if (NS_taccess(path, F_OK)) {
      88               1 :     return false;
      89                 :   }
      90                 : 
      91               1 :   FILE *inFP = NS_tfopen(path, NS_T("rb"));
      92               1 :   if (!inFP) {
      93               0 :     return false;
      94                 :   }
      95                 : 
      96                 :   struct stat ms;
      97               1 :   if (fstat(fileno(inFP), &ms)) {
      98               0 :     return false;
      99                 :   }
     100                 : 
     101               1 :   char *mbuf = (char *) malloc(ms.st_size + 1);
     102               1 :   if (!mbuf) {
     103               0 :     return false;
     104                 :   }
     105                 : 
     106               1 :   size_t r = ms.st_size;
     107               1 :   char *rb = mbuf;
     108               1 :   size_t c = fread(rb, sizeof(char), 50, inFP);
     109               1 :   r -= c;
     110               1 :   rb += c;
     111               1 :   if (c == 0 && r) {
     112               0 :     return false;
     113                 :   }
     114               1 :   mbuf[ms.st_size] = '\0';
     115               1 :   rb = mbuf;
     116                 : 
     117               1 :   fclose(inFP);
     118               1 :   inFP = NULL;
     119               1 :   return strcmp(rb, expected) == 0;
     120                 : }
     121                 : 
     122                 : #ifdef XP_WIN
     123                 : /**
     124                 :  * Verifies the trust of the specified file path.
     125                 :  *
     126                 :  * @param  filePath  The file path to check.
     127                 :  * @return ERROR_SUCCESS if successful, or the last error code otherwise.
     128                 :  */
     129                 : DWORD
     130                 : VerifyCertificateTrustForFile(LPCWSTR filePath)
     131                 : {
     132                 :   // Setup the file to check.
     133                 :   WINTRUST_FILE_INFO fileToCheck;
     134                 :   ZeroMemory(&fileToCheck, sizeof(fileToCheck));
     135                 :   fileToCheck.cbStruct = sizeof(WINTRUST_FILE_INFO);
     136                 :   fileToCheck.pcwszFilePath = filePath;
     137                 : 
     138                 :   // Setup what to check, we want to check it is signed and trusted.
     139                 :   WINTRUST_DATA trustData;
     140                 :   ZeroMemory(&trustData, sizeof(trustData));
     141                 :   trustData.cbStruct = sizeof(trustData);
     142                 :   trustData.pPolicyCallbackData = NULL;
     143                 :   trustData.pSIPClientData = NULL;
     144                 :   trustData.dwUIChoice = WTD_UI_NONE;
     145                 :   trustData.fdwRevocationChecks = WTD_REVOKE_NONE; 
     146                 :   trustData.dwUnionChoice = WTD_CHOICE_FILE;
     147                 :   trustData.dwStateAction = 0;
     148                 :   trustData.hWVTStateData = NULL;
     149                 :   trustData.pwszURLReference = NULL;
     150                 :   // no UI
     151                 :   trustData.dwUIContext = 0;
     152                 :   trustData.pFile = &fileToCheck;
     153                 : 
     154                 :   GUID policyGUID = WINTRUST_ACTION_GENERIC_VERIFY_V2;
     155                 :   // Check if the file is signed by something that is trusted.
     156                 :   return WinVerifyTrust(NULL, &policyGUID, &trustData);
     157                 : }
     158                 : 
     159                 : #endif
     160                 : 
     161               5 : int NS_main(int argc, NS_tchar **argv)
     162                 : {
     163                 : 
     164               5 :   if (argc < 3) {
     165                 :     fprintf(stderr, \
     166                 :             "\n" \
     167                 :             "Application Update Service Test Helper\n" \
     168                 :             "\n" \
     169                 :             "Usage: WORKINGDIR INFILE OUTFILE -s SECONDS [FILETOLOCK]\n"  \
     170                 :             "   or: WORKINGDIR LOGFILE [ARG2 ARG3...]\n" \
     171                 :             "   or: signature-check filepath\n" \
     172                 :             "\n" \
     173                 :             "  WORKINGDIR  \tThe relative path to the working directory to use.\n" \
     174                 :             "  INFILE      \tThe relative path from the working directory for the file to\n" \
     175                 :             "              \tread actions to perform such as finish.\n" \
     176                 :             "  OUTFILE     \tThe relative path from the working directory for the file to\n" \
     177                 :             "              \twrite status information.\n" \
     178                 :             "  SECONDS     \tThe number of seconds to sleep.\n" \
     179                 :             "  FILETOLOCK  \tThe relative path from the working directory to an existing\n" \
     180                 :             "              \tfile to open exlusively.\n" \
     181                 :             "              \tOnly available on Windows platforms and silently ignored on\n" \
     182                 :             "              \tother platforms.\n" \
     183                 :             "  LOGFILE     \tThe relative path from the working directory to log the\n" \
     184                 :             "              \tcommand line arguments.\n" \
     185                 :             "  ARG2 ARG3...\tArguments to write to the LOGFILE after the preceding command\n" \
     186                 :             "              \tline arguments.\n" \
     187                 :             "\n" \
     188                 :             "Note: All paths must be relative.\n" \
     189               0 :             "\n");
     190               0 :     return 1;
     191                 :   }
     192                 : 
     193               5 :   if (!NS_tstrcmp(argv[1], NS_T("check-signature"))) {
     194                 : #ifdef XP_WIN
     195                 :     if (ERROR_SUCCESS == VerifyCertificateTrustForFile(argv[2])) {
     196                 :       return 0;
     197                 :     } else {
     198                 :       return 1;
     199                 :     }
     200                 : #else 
     201                 :     // Not implemented on non-Windows platforms
     202               0 :     return 1;
     203                 : #endif
     204                 :   }
     205                 : 
     206               5 :   if (!NS_tstrcmp(argv[1], NS_T("wait-for-service-stop"))) {
     207                 : #ifdef XP_WIN
     208                 :     const int maxWaitSeconds = NS_ttoi(argv[3]);
     209                 :     LPCWSTR serviceName = argv[2];
     210                 :     DWORD serviceState = WaitForServiceStop(serviceName, maxWaitSeconds);
     211                 :     if (SERVICE_STOPPED == serviceState) {
     212                 :       return 0;
     213                 :     } else {
     214                 :       return serviceState;
     215                 :     }
     216                 : #else 
     217                 :     // Not implemented on non-Windows platforms
     218               0 :     return 1;
     219                 : #endif
     220                 :   }
     221                 : 
     222               5 :   if (!NS_tstrcmp(argv[1], NS_T("wait-for-application-exit"))) {
     223                 : #ifdef XP_WIN
     224                 :     const int maxWaitSeconds = NS_ttoi(argv[3]);
     225                 :     LPCWSTR application = argv[2];
     226                 :     DWORD ret = WaitForProcessExit(application, maxWaitSeconds);
     227                 :     if (ERROR_SUCCESS == ret) {
     228                 :       return 0;
     229                 :     } else if (WAIT_TIMEOUT == ret) {
     230                 :       return 1;
     231                 :     } else {
     232                 :       return 2;
     233                 :     }
     234                 : #else 
     235                 :     // Not implemented on non-Windows platforms
     236               0 :     return 1;
     237                 : #endif
     238                 :   }
     239                 : 
     240               5 :   int i = 0;
     241                 : 
     242               5 :   if (NS_tchdir(argv[1]) != 0) {
     243               0 :     return 1;
     244                 :   }
     245                 : 
     246                 :   // File in use test helper section
     247               5 :   if (!NS_tstrcmp(argv[4], NS_T("-s"))) {
     248                 :     NS_tchar inFilePath[MAXPATHLEN];
     249                 :     NS_tsnprintf(inFilePath, sizeof(inFilePath)/sizeof(inFilePath[0]),
     250               1 :                  NS_T("%s"), argv[2]);
     251                 :     NS_tchar outFilePath[MAXPATHLEN];
     252                 :     NS_tsnprintf(outFilePath, sizeof(outFilePath)/sizeof(outFilePath[0]),
     253               1 :                  NS_T("%s"), argv[3]);
     254                 : 
     255               1 :     int seconds = NS_ttoi(argv[5]);
     256                 : #ifdef XP_WIN
     257                 :     HANDLE hFile = INVALID_HANDLE_VALUE;
     258                 :     if (argc == 7) {
     259                 :       hFile = CreateFileW(argv[6],
     260                 :                           DELETE | GENERIC_WRITE, 0,
     261                 :                           NULL, OPEN_EXISTING, 0, NULL);
     262                 :       if (hFile == INVALID_HANDLE_VALUE) {
     263                 :         WriteMsg(outFilePath, "error_locking");
     264                 :         return 1;
     265                 :       }
     266                 :     }
     267                 : 
     268                 :     WriteMsg(outFilePath, "sleeping");
     269                 :     while (!CheckMsg(inFilePath, "finish\n") && i++ <= seconds)  {
     270                 :       Sleep(1000);
     271                 :     }
     272                 : 
     273                 :     if (argc == 7) {
     274                 :       CloseHandle(hFile);
     275                 :     }
     276                 : #else
     277               1 :     WriteMsg(outFilePath, "sleeping");
     278               3 :     while (!CheckMsg(inFilePath, "finish\n") && i++ <= seconds)  {
     279               1 :       sleep(1);
     280                 :     }
     281                 : #endif
     282               1 :     WriteMsg(outFilePath, "finished");
     283               1 :     return 0;
     284                 :   }
     285                 : 
     286                 :   // Command line argument test helper section
     287                 :   NS_tchar logFilePath[MAXPATHLEN];
     288                 :   NS_tsnprintf(logFilePath, sizeof(logFilePath)/sizeof(logFilePath[0]),
     289               4 :                NS_T("%s"), argv[2]);
     290                 : 
     291               4 :   FILE* logFP = NS_tfopen(logFilePath, NS_T("wb"));
     292              20 :   for (i = 1; i < argc; ++i) {
     293              16 :     fprintf(logFP, LOG_S "\n", argv[i]);
     294                 :   }
     295                 : 
     296               4 :   fclose(logFP);
     297               4 :   logFP = NULL;
     298                 : 
     299               4 :   return 0;
     300                 : } 

Generated by: LCOV version 1.7