root/lang/c/AutoUpdater/AutoUpdater.c @ 34710

Revision 34710, 35.1 kB (checked in by saturday06, 5 years ago)

がんばってそうじした

Line 
1#include <stdio.h>
2#include <string.h>
3#include <stdlib.h>
4#include <time.h>
5#include <malloc.h>
6
7#define AUI_NO_UNDEFINE_MACROS
8#include "AutoUpdater.h"
9
10#ifdef AUI_WINDOWS
11#include <wininet.h>
12#endif
13
14typedef struct {
15    char created_sign;
16    AU_Option option;
17
18    TCHAR* description;
19    double download_progress;
20    int new_version_number;
21
22    struct {
23        FILE* file;
24        int foo;
25    } update_information;
26
27    struct {
28        FILE* file;
29        int bar;
30        int baz;
31    } progress;
32
33#ifdef AUI_WINDOWS
34    HINTERNET internet_handle;
35    HANDLE url_handle_event;
36    HINTERNET url_handle;
37    HANDLE InternetReadFileExA_event;
38#endif
39
40} AUI_ContextData;
41
42
43#ifdef AUI_WINDOWS
44#ifdef __CYGWIN__
45  #if defined(UNICODE) || defined(_UNICODE)
46    #include <wchar.h>
47    static wchar_t *wcsdup(const wchar_t *s) {
48        size_t len;
49        len = wcslen(s) + 1;
50        wchar_t* buf = malloc(len * sizeof(wchar_t));
51        memcpy(buf, s, len * sizeof(wchar_t));
52        return buf;
53    }
54    #define _tcsdup wcsdup
55  #else
56    #define _tcsdup strdup
57  #endif
58#else
59  #include <tchar.h>
60  #ifdef _MSC_VER
61    #pragma comment(lib, "wininet.lib")
62  #endif
63  static void AUI_Sleep(unsigned int mili_seconds) {
64      Sleep(mili_seconds);
65  }
66#endif
67#endif
68
69#ifndef _countof
70  #define _countof(array) (sizeof(array) / sizeof(array[0]))
71#endif
72
73/* -----------------------------------------------------------------------
74    Internal functions
75   ----------------------------------------------------------------------- */
76//int AUI_ConvertUTF8ToAppCode(const char* utf8_str, TCHAR* appcode_str, size_t appcode_str_bytes);
77//int AUI_Download(TCHAR* url);
78
79#ifdef AUI_WINDOWS
80/* -----------------------------------------------------------------------
81    Windows
82   ----------------------------------------------------------------------- */
83
84#ifdef _MSC_VER
85#pragma warning (disable: 4996)
86#endif
87
88static HINSTANCE AUI_mlang_dll = NULL;
89typedef HRESULT (WINAPI *AUI_ConvertINetString_type)(
90    LPDWORD lpdwMode,
91    DWORD dwSrcEncoding,
92    DWORD dwDstEncoding,
93    LPCSTR lpSrcStr,
94    LPINT lpnSrcSize,
95    LPBYTE lpDstStr,
96    LPINT lpnDstSize
97);
98static AUI_ConvertINetString_type AUI_ConvertINetString_pointer = NULL;
99
100
101//typedef HRESULT (WINAPI *ConvertINetMultiByteToUnicode_type)(          LPDWORD lpdwMode,
102//    DWORD dwSrcEncoding,
103//    LPCSTR lpSrcStr,
104//    LPINT lpnMultiCharCount,
105//    LPWSTR lpDstStr,
106//    LPINT lpnWideCharCount
107//);
108//ConvertINetMultiByteToUnicode_type ConvertINetMultiByteToUnicode_p = NULL;
109
110static int AUI_ConvertUTF8ToAppCode(const char* utf8_str, TCHAR* appcode_str, size_t appcode_str_bytes) {
111    HRESULT hresult;
112    DWORD dwMode = 0;
113    DWORD dwSrcEncoding = 65001; // UTF-8
114    DWORD dwDstEncoding = 1200;  // UTF-16LE
115
116    memset(appcode_str, 0, appcode_str_bytes);
117
118#ifdef _UNICODE
119    dwDstEncoding = 1200; // UTF-16LE
120#else
121    dwDstEncoding = GetACP();
122#endif
123
124    if (!AUI_mlang_dll) {
125        AUI_mlang_dll = LoadLibrary(_T("mlang.dll"));
126        if (!AUI_mlang_dll) {
127            return 0;
128        }
129        AUI_ConvertINetString_pointer = (AUI_ConvertINetString_type)GetProcAddress(AUI_mlang_dll,"ConvertINetString");
130        if (!AUI_ConvertINetString_pointer) {
131            return 0;
132        }
133        //ConvertINetMultiByteToUnicode_p = (ConvertINetMultiByteToUnicode_type)GetProcAddress(AUI_mlang_dll,"ConvertINetString");
134        //if (!ConvertINetMultiByteToUnicode_p) {
135        //    return 0;
136        //}
137    }
138
139    { // �o�b�t�@�̑傫���͏��Ȃ߂Ɏw��        INT appcode_str_bytes2 = appcode_str_bytes - 5;
140        if (appcode_str_bytes2 < 1) {
141            return 0;
142        }
143        hresult = AUI_ConvertINetString_pointer(
144            &dwMode,
145            dwSrcEncoding,
146            dwDstEncoding,
147            utf8_str,
148            NULL,
149            (LPBYTE)appcode_str, //XXX OK??
150            &appcode_str_bytes2
151        );
152    }
153    // S_OK Performed the conversion successfully.
154    // S_FALSE The specified conversion is not supported on the system.
155    // E_FAIL An error has occurred.
156    if (hresult != S_OK) {
157        return 0;
158    }
159    //{
160    //    DWORD dwSrcEncoding = 1200;  // UTF-16LE
161    //    hresult = ConvertINetMultiByteToUnicode_p(
162    //        &dwMode,
163    //        dwSrcEncoding,
164    //        buf,
165    //        NULL,
166    //        appcode_str,
167    //        &appcode_str_bytes
168    //    );
169
170    //    // S_OK Performed the conversion successfully.
171    //    // S_FALSE The specified conversion is not supported on the system.
172    //    // E_FAIL An error has occurred.
173    //    if (hresult != S_OK) {
174    //        return 0;
175    //    }
176    //}
177    return 1;
178}
179
180#else
181/* -----------------------------------------------------------------------
182    posix
183   ----------------------------------------------------------------------- */
184
185#endif
186
187//static int AUI_IsBadReadString(void* buffer_, size_t char_bytes) {
188//    char* buffer = (char*)buffer_;
189//    void* null_char = alloca(char_bytes);
190//    memset(null_char, 0, char_bytes);
191//
192//    for (;;) {
193//        char* buffer_old = buffer;
194//        if (IsBadReadPtr(buffer, char_bytes)) {
195//            return 1;
196//        }
197//        if (memcmp(buffer, null_char, char_bytes) == 0) {
198//            return 0;
199//        }
200//        buffer += char_bytes;
201//        if (buffer < buffer_old) {
202//            return 1;
203//        }
204//    }
205//    return 1;
206//}
207
208/* -----------------------------------------------------------------------
209    End Preprocessor configuration 3
210   ----------------------------------------------------------------------- */
211
212static AU_Result AUI_CreateContext(AUI_ContextData* context, AU_Option* option) {
213
214#ifdef AUI_WINDOWS
215    {
216        if (IsBadReadPtr(option, sizeof(*option)) ||
217            IsBadReadPtr(option->url, 1)) {
218            return AU_ERROR_INVALID_OPTION;
219        }
220    }
221#endif
222
223    {
224        AU_Option new_option = *option;
225
226        new_option.url = _tcsdup(option->url);
227        if (!new_option.url) {
228            return AU_ERROR_BAD_ALLOC;
229        }
230        *((AU_Option*)&(context)->option) = new_option;
231    }
232
233    {
234
235#ifdef AUI_WINDOWS
236
237        /*
238        url_bytes = strlen(context->url_list[0]);
239        context->protocol = calloc(url_bytes + 1, 1);
240        if (!context->protocol) {
241            return AU_ERROR_BAD_ALLOC;
242        }
243        context->server = calloc(url_bytes + 1, 1);
244        if (!context->server) {
245            free(context->protocol);
246            return AU_ERROR_BAD_ALLOC;
247        }
248        context->path = calloc(url_bytes + 1, 1);
249        if (!context->path) {
250            free(context->protocol);
251            free(context->server);
252            return AU_ERROR_BAD_ALLOC;
253        }
254        if (sscanf(context->url_list[0],        "%[^:]://%[^:]:%d%s", context->protocol, context->server, &context->port, context->path) >= 3) {
255        } else if (sscanf(context->url_list[0], "%[^:]://%[^/]%s", context->protocol, context->server, context->path) >= 2) {
256            if (strcmp(context->protocol, "http") == 0) {
257                context->port = 80;
258            } else if (strcmp(context->protocol, "https") == 0) {
259                context->port = 443;
260            } else if (strcmp(context->protocol, "ftp") == 0) {
261                context->port = 20;
262            }
263        } else {
264            free(context->protocol);
265            free(context->server);
266            free(context->path);
267            return AU_ERROR_INVALID_URL_FORMAT;
268        }
269        if (context->path[0] == 0) {
270            context->path[0] = '/';
271        } else if (context->path[0] != '/') {
272            free(context->protocol);
273            free(context->server);
274            free(context->path);
275            return AU_ERROR_INVALID_URL_FORMAT;
276        }
277        */
278#endif
279    }
280   
281    return AU_OK;
282}
283
284static void AUI_UpdaterThread(AU_Context context) {
285   
286}
287
288static AU_Result AUI_DestroyContext(AUI_ContextData* context) {
289    // free pointers
290    if (context->description != NULL) {
291        free(context->description);
292    }
293    free(context->option.url);
294    if (context->update_information.file) {
295        fclose(context->update_information.file);
296    }
297
298    // clear memory
299    memset(context, 0, sizeof(*context));
300
301    free(context);
302    return AU_OK;
303}
304
305#define AUI_DESCRIPTION_BYTES  2000
306#define AUI_STRINGIZE(text)    #text
307#define AUI_CONFIGFILE_BYTES   (AUI_DESCRIPTION_BYTES + 2000)
308
309static void CALLBACK AUI_InternetStatusCallback(
310          HINTERNET hInternet,
311          DWORD_PTR dwContext,
312          DWORD dwInternetStatus,
313          LPVOID lpvStatusInformation,
314          DWORD dwStatusInformationLength) {
315
316    AUI_ContextData* context = (AUI_ContextData*)dwContext;
317
318        switch (dwInternetStatus) {
319        case INTERNET_STATUS_HANDLE_CREATED: {
320                INTERNET_ASYNC_RESULT* a = (INTERNET_ASYNC_RESULT*)lpvStatusInformation;
321        BOOL result = FALSE;
322        context->url_handle = (HINTERNET)(a->dwResult);
323        result = SetEvent(context->url_handle_event);
324        if (!result) {
325            // error
326        }
327                break;
328        }
329        case INTERNET_STATUS_REQUEST_SENT: {
330                //DWORD* lpBytesSent = (DWORD*)lpStatusInfo;
331                break;
332        }
333        case INTERNET_STATUS_REQUEST_COMPLETE: {
334                INTERNET_ASYNC_RESULT* pAsyncRes = (INTERNET_ASYNC_RESULT *)lpvStatusInformation;
335                //TRACE("Function call finished  dwResult:%d  dwError:%d\n", pAsyncRes->dwResult, pAsyncRes->dwError);
336                //if (NULL == pAsyncRes->dwResult) {
337                        // pAsyncRes->dwResult is a pointer to HINTERNET. NULL means an error has occured.
338                        //pThis->m_errInfo = CErrInfo(CErrInfo::errSystem, pAsyncRes->dwError);
339                //}
340                //::SetEvent(pThis->m_hEventRequestComplete);
341                break;
342        }
343        case INTERNET_STATUS_RECEIVING_RESPONSE:
344                //TRACE0("Receiving Response\n");
345                break;
346        case INTERNET_STATUS_RESPONSE_RECEIVED: {
347                //DWORD *dwBytesReceived = (DWORD*)lpStatusInfo;
348                //if (*dwBytesReceived == 0) {
349                //      pThis->m_bAllDone = true;
350                //}
351                //TRACE("Received %d\n", *dwBytesReceived);
352                break;
353        }
354        default:
355                break;
356        }
357}
358
359static AU_Result AUI_GetUpdateInformation(AUI_ContextData* context, AU_UpdateInformation* infomation) {   
360    if (!context->update_information.file) {
361        context->update_information.file = tmpfile();
362        if (!context->update_information.file) {
363            AUI_Sleep(1000);
364            context->update_information.file = tmpfile();
365            if (!context->update_information.file) {
366                return AU_ERROR_NETWORK;
367            }
368        }
369    }
370   
371#ifdef AUI_WINDOWS
372    if (!context->internet_handle) {
373        context->internet_handle = InternetOpen(TEXT("test"), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, INTERNET_FLAG_ASYNC);
374        if (!context->internet_handle) {
375            return AU_ERROR_NETWORK;
376        }
377        if (InternetSetStatusCallback(context->internet_handle, AUI_InternetStatusCallback)
378             == INTERNET_INVALID_STATUS_CALLBACK) {
379            //return AU_ERROR_NETWORK;
380        }
381    }
382    if (!context->url_handle_event) {
383        DWORD e = 0;
384        context->url_handle_event = CreateEvent(NULL, FALSE, FALSE, NULL);
385                    InternetOpenUrl(
386                    context->internet_handle,
387                    context->option.url,
388                    NULL,
389                    (DWORD)-1,
390                    INTERNET_FLAG_RELOAD,
391                    (DWORD_PTR)context);
392        e = GetLastError();
393        if (e != ERROR_IO_PENDING) {
394            return AU_ERROR_NETWORK;
395        }
396    }
397    if (!context->url_handle_event) {
398        return AU_ERROR_NETWORK;
399    }
400    {
401        DWORD e = WaitForSingleObject(context->url_handle_event, 0);
402        switch (e) {
403        case WAIT_OBJECT_0:
404            break;
405        case WAIT_TIMEOUT:
406            return AU_IO_PENDING;
407            break;
408        default:
409            return AU_ERROR_NETWORK;
410            break;
411        }
412    }
413
414    {
415        char buffer[1000];
416        BOOL read_result = 0;
417        INTERNET_BUFFERSA ib;
418        ib.dwStructSize = sizeof(ib);
419        ib.Next = 0;
420        ib.lpcszHeader = 0;
421        ib.dwHeadersLength = 0;
422        ib.dwHeadersTotal = 0;
423        ib.lpvBuffer = buffer;
424        ib.dwBufferLength = sizeof(buffer);
425        ib.dwBufferTotal = 0;
426        ib.dwOffsetLow = 0;
427        ib.dwOffsetHigh = 0;
428
429        for (;;) {
430            DWORD e = GetLastError();
431                    read_result = InternetReadFileExA(
432                                        context->url_handle,
433                                        &ib,
434                                        IRF_NO_WAIT,
435                                        (DWORD_PTR)context);
436
437            if (e == ERROR_IO_PENDING) {
438                return AU_IO_PENDING;
439            }
440
441            if (read_result) {
442                if (ib.dwOffsetLow == 0) {
443                    break;
444                }
445                if (fwrite(buffer, 1, ib.dwOffsetLow, context->update_information.file) != ib.dwOffsetLow) {
446                    return AU_ERROR_NETWORK;
447                }
448            }
449        }
450        {
451            char test[2000];
452            fseek(context->update_information.file, 0, SEEK_SET);
453            fread(test, 1, 2000, context->update_information.file);
454        }
455    }
456#endif
457    {
458        char text[AUI_CONFIGFILE_BYTES];
459//        int debug = 0;
460        int version_number = 0;
461        char description[AUI_DESCRIPTION_BYTES]; //XXX size!
462        int result = 0;     
463        memset(text, 0, sizeof(text));
464        memset(description, 0, sizeof(description));
465/*
466        result = sscanf(text,
467            " [%d]"
468            " debug = %1d"
469            " description = %" AUI_STRINGIZE(AUI_DESCRIPTION_BYTES) " "  //XXX 2^32 = 4 294 967 296 (depends on 32bit)
470            " %s"  //XXX 2000
471            , &debug, &version_number, description);
472*/
473        if (result == EOF || result != 3) {
474            return AU_ERROR_INVALID_CONFIG_FORMAT;
475        }
476
477        context->new_version_number = version_number;
478
479        //{
480        //    TCHAR buf[4096];
481        //    AUI_ConvertUTF8ToAppCode(description, buf, sizeof(buf));
482        //    context->description = _tcsdup(buf);
483        //    if (context->description == NULL) {
484        //        return AU_ERROR_BAD_ALLOC;
485        //    }
486        //}
487    }
488
489    return AU_OK;
490}
491
492
493static AU_Result AUI_Update(AUI_ContextData* context) {
494
495//    if (base_path == NULL) {
496//        base_path = _T(".");
497//    }
498
499    return AU_OK;
500}
501
502static AU_Result AUI_Cancel(AUI_ContextData* context) {
503    return AU_OK;
504}
505
506/* -----------------------------------------------------------------------
507    Interfaces
508   ----------------------------------------------------------------------- */
509#define AU_CREATED_SIGN 72
510
511#ifdef AUI_WINDOWS
512#define AUI_API_PRECONDITION \
513    AUI_ContextData* context_data = (AUI_ContextData*)context; \
514    { \
515        if (\
516            IsBadReadPtr(context_data, sizeof(context_data))                                    || \
517            IsBadWritePtr(context_data, sizeof(context_data))                                   || \
518            (context_data->description != NULL && IsBadWritePtr(context_data->description, 1))  || \
519            (context_data->option.url  != NULL && IsBadWritePtr(context_data->option.url, 1))   || \
520            \
521            (context_data)->created_sign != AU_CREATED_SIGN) { \
522            return AU_ERROR_INVALID_CONTEXT; \
523        } \
524    }
525#else
526#define AUI_API_PRECONDITION \
527    AUI_ContextData* context_data = (AUI_ContextData*)context; \
528    { \
529        if (context_data == NULL || context_data->created_sign != AU_CREATED_SIGN) { \
530            return AU_ERROR_INVALID_CONTEXT; \
531        } \
532    }
533#endif
534
535AU_Result AU_CreateContext(AU_Context* pcontext, AU_Option* option) {
536    AU_Result result;
537    AU_Context context = NULL;
538
539    if (IsBadReadPtr(pcontext, sizeof(*pcontext))) {
540        return AU_ERROR_INVALID_CONTEXT;
541    }
542
543    context = (AU_Context)malloc(sizeof(AUI_ContextData));
544    if (!context) {
545        return AU_ERROR_BAD_ALLOC;
546    }
547   
548    {
549        AUI_ContextData* context_data = (AUI_ContextData*)context;
550        memset(context_data, 0, sizeof(*context_data));
551        context_data->created_sign = AU_CREATED_SIGN;
552    }
553
554    {
555        AUI_API_PRECONDITION;
556        result = AUI_CreateContext(context_data, option);
557        if (result == AU_OK) {
558            *pcontext = context;
559        }
560        return result;
561    }
562}
563
564AU_Result AU_DestroyContext(AU_Context context) {
565    AUI_API_PRECONDITION;
566    return AUI_DestroyContext(context_data);
567}
568
569AU_Result AU_GetUpdateInformation(AU_Context context, AU_UpdateInformation* infomation) {
570    AUI_API_PRECONDITION;
571    return AUI_GetUpdateInformation(context_data, infomation);
572}
573
574AU_Result AU_Update(AU_Context context) {
575    AUI_API_PRECONDITION;
576    return AUI_Update(context_data);
577}
578
579AU_Result AU_Cancel(AU_Context context) {
580    AUI_API_PRECONDITION;
581    return AUI_Cancel(context_data);
582}
583
584
585
586
587
588#ifdef AUI_WINDOWS
589/*
590HRESULT my_invoke_helper(IDispatch* dispatch, OLECHAR* member_name, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult) {
591    HRESULT result = S_OK;
592    DISPID dispid;
593    result = dispatch->lpVtbl->GetIDsOfNames(dispatch, &IID_NULL, &member_name, 1, GetUserDefaultLCID(), &dispid);
594    if (FAILED(result)) {
595        return result;
596    }
597    result = dispatch->lpVtbl->Invoke(dispatch, dispid, &IID_NULL, GetUserDefaultLCID(), wFlags, pDispParams, pVarResult, NULL, NULL);
598    return result;
599}
600*/
601//void ziptest(void) {
602//    HRESULT result = S_OK;
603//    DISPID dispid;
604//    VARIANT invoke_result;
605//    IDispatch* ie = NULL;
606//    IDispatch* ie_Document = NULL;
607//    IDispatch* ie_Document_Application = NULL;
608//    IDispatch* ie_Document_Application_NameSpace = NULL; // destination folder
609//    IDispatch* ie_Document_Folder = NULL;
610//    IDispatch* ie_Document_Folder_Items = NULL; // zip folder items
611//    OLECHAR zipfile_name[] = OLESTR("d:\\foo.zip");
612//    OLECHAR destdir_name[] = OLESTR("d:\\bar");
613//
614//    /*
615//    Set ie = GetObject("new:{C08AFD90-F2A1-11D1-8455-00A0C91F3880}")
616//    ie.Navigate "c:\\zipfile.zip"
617//    Do While ie.Busy Or ie.ReadyState<>4
618//        WScript.AUI_Sleep 100
619//    Loop
620//    ie.Document.Application.NameSpace("c:\\destination_dir\\").CopyHere ie.Document.Folder.Items()
621//    */
622//
623//    // ---------------------------------------------
624//    // CoInitialize
625//    // ---------------------------------------------
626//    {
627//        result = CoInitialize(NULL);
628//      switch (result)
629//          {
630//      case S_OK :
631//              break;
632//          case S_FALSE:
633//                  // CoInitialize: The COM library is already initialized on this thread
634//                  break;
635//          case RPC_E_CHANGED_MODE:
636//                  // CoInitialize: A previous call to CoInitializeEx specified the concurrency model for this thread as multithread apartment (MTA). If running Windows 2000, this could also mean that a change from neutral-threaded apartment to single-threaded apartment occurred.
637//                  break;
638//      }
639//    }
640//
641//    // ---------------------------------------------
642//    // ie
643//    // ---------------------------------------------
644//    {
645//        OLECHAR clsid_str_pool[] = OLESTR("{C08AFD90-F2A1-11D1-8455-00A0C91F3880}");
646//        LPOLESTR clsid_str = clsid_str_pool;
647//        CLSID clsid;
648//
649//        result = CLSIDFromString(clsid_str, &clsid);
650//     
651//        switch (result)
652//        {
653//        case NOERROR:
654//            //The CLSID was obtained successfully.
655//            break;
656//        case E_INVALIDARG:
657//            return;
658//            break;
659//        case CO_E_CLASSSTRING:
660//            //The class string was improperly formatted.
661//            return;
662//            break;
663//        case REGDB_E_CLASSNOTREG:
664//            //The CLSID corresponding to the class string was not found in the registry.
665//            return;
666//            break;
667//        case REGDB_E_READREGDB:
668//            //The registry could not be opened for reading.
669//            return;
670//            break;
671//        default:
672//            //
673//            return;
674//            break;
675//        }
676//
677//      result = CoCreateInstance(&clsid, NULL, CLSCTX_SERVER, &IID_IDispatch, &ie);
678//        switch (result)
679//          {
680//          case S_OK:
681//                  break;
682//          case REGDB_E_CLASSNOTREG:
683//                  //Debug("");
684//                  return;
685//                  break;
686//          case CLASS_E_NOAGGREGATION:
687//                  //Debug("This class cannot be created as part of an aggregate");
688//                  return;
689//                  break;
690//          case E_NOINTERFACE:
691//                  //Debug("The specified class does not implement the requested interface, or the controlling IUnknown does not expose the requested interface");
692//                  return;
693//                  break;
694//          default:
695//                  //Debug("CoCreateInstance unknown error: " << result);
696//                  return;
697//                  break;
698//          }
699//
700//          if (ie == NULL)
701//        {
702//            //Debug("pDispatch is NULL");
703//        }
704//    }
705//
706//    // ---------------------------------------------
707//    // ie.Navigate("filename")
708//    // ---------------------------------------------   
709//    {
710//        OLECHAR property_name_pool[] = OLESTR("Navigate");
711//        LPOLESTR property_name = property_name_pool;
712//        VARIANTARG varg[1];
713//        DISPPARAMS params;
714//
715//        BSTR bstr_zipfile_name;
716//
717//        result = ie->lpVtbl->GetIDsOfNames(ie, &IID_NULL, &property_name, 1, GetUserDefaultLCID(), &dispid);
718//        if (FAILED(result)) {
719//            return;
720//        }
721//
722//        bstr_zipfile_name = SysAllocString(zipfile_name);
723//        if (bstr_zipfile_name == NULL) {
724//            return;
725//        }
726//
727//        VariantInit(&varg[0]);
728//        varg[0].vt = VT_BSTR;
729//        varg[0].bstrVal = bstr_zipfile_name;
730//
731//        params.cArgs = 1;
732//        params.cNamedArgs = 0;
733//        params.rgdispidNamedArgs = 0;
734//        params.rgvarg = varg;
735//
736//        result = ie->lpVtbl->Invoke(ie, dispid, &IID_NULL, GetUserDefaultLCID(), DISPATCH_METHOD, &params, &invoke_result, NULL, NULL);
737//
738//        SysFreeString(bstr_zipfile_name);
739//
740//        if (FAILED(result)) {
741//            return;
742//        }
743//    }
744//
745//    // ---------------------------------------------
746//    // wait until Navigate Complete
747//    // ---------------------------------------------
748//    {
749//        WAIT_UNTIL_NAVIGATE_COMPLETE:
750//        // ---------------------------------------------
751//        // ie.Busy
752//        // ---------------------------------------------
753//        {
754//            DISPPARAMS params = {NULL,NULL,0,0};
755//            OLECHAR property_name_pool[] = OLESTR("Busy");
756//            LPOLESTR property_name = property_name_pool;
757//
758//            result = ie->lpVtbl->GetIDsOfNames(ie, &IID_NULL, &property_name, 1, GetUserDefaultLCID(), &dispid);
759//            if (FAILED(result)) {
760//                return;
761//            }
762//
763//            result = ie->lpVtbl->Invoke(ie, dispid, &IID_NULL, GetUserDefaultLCID(), DISPATCH_PROPERTYGET, &params, &invoke_result, NULL, NULL);
764//            if (FAILED(result)) {
765//                return;
766//            }
767//
768//            if (invoke_result.boolVal) {
769//                AUI_Sleep(500);
770//                goto WAIT_UNTIL_NAVIGATE_COMPLETE;
771//            }
772//        }
773//
774//        // ---------------------------------------------
775//        // ie.ReadyState
776//        // ---------------------------------------------
777//        {
778//            DISPPARAMS params = {NULL,NULL,0,0};
779//            OLECHAR property_name_pool[] = OLESTR("ReadyState");
780//            LPOLESTR property_name = property_name_pool;
781//
782//            result = ie->lpVtbl->GetIDsOfNames(ie, &IID_NULL, &property_name, 1, GetUserDefaultLCID(), &dispid);
783//            if (FAILED(result)) {
784//                return;
785//            }
786//
787//            result = ie->lpVtbl->Invoke(ie, dispid, &IID_NULL, GetUserDefaultLCID(), DISPATCH_PROPERTYGET, &params, &invoke_result, NULL, NULL);
788//            if (FAILED(result)) {
789//                return;
790//            }
791//
792//            if (invoke_result.lVal != 4) {
793//                AUI_Sleep(500);
794//                goto WAIT_UNTIL_NAVIGATE_COMPLETE;
795//            }
796//        }
797//    } // wait until Navigate Complete
798//
799//    // ---------------------------------------------
800//    // ie.Document
801//    // ---------------------------------------------
802//    {
803//        DISPPARAMS params = {NULL,NULL,0,0};
804//        OLECHAR property_name_pool[] = OLESTR("Document");
805//        LPOLESTR property_name = property_name_pool;
806//
807//        result = ie->lpVtbl->GetIDsOfNames(ie, &IID_NULL, &property_name, 1, GetUserDefaultLCID(), &dispid);
808//        if (FAILED(result)) {
809//            return;
810//        }
811//
812//        result = ie->lpVtbl->Invoke(ie, dispid, &IID_NULL, GetUserDefaultLCID(), DISPATCH_PROPERTYGET, &params, &invoke_result, NULL, NULL);
813//        if (FAILED(result)) {
814//            return;
815//        }
816//
817//        ie_Document = invoke_result.pdispVal;
818//    }
819//
820//    // ---------------------------------------------
821//    // ie.Document.Application
822//    // ---------------------------------------------
823//    {
824//        DISPPARAMS params = {NULL,NULL,0,0};
825//        OLECHAR property_name_pool[] = OLESTR("Application");
826//        LPOLESTR property_name = property_name_pool;
827//
828//        result = ie->lpVtbl->GetIDsOfNames(ie_Document, &IID_NULL, &property_name, 1, GetUserDefaultLCID(), &dispid);
829//        if (FAILED(result)) {
830//            return;
831//        }
832//
833//        result = ie->lpVtbl->Invoke(ie_Document, dispid, &IID_NULL, GetUserDefaultLCID(), DISPATCH_PROPERTYGET, &params, &invoke_result, NULL, NULL);
834//        if (FAILED(result)) {
835//            return;
836//        }
837//
838//        ie_Document_Application = invoke_result.pdispVal;
839//    }
840//
841//    // ---------------------------------------------
842//    // ie.Document.Application.NameSpace("filename")
843//    // ---------------------------------------------   
844//    {
845//        OLECHAR property_name_pool[] = OLESTR("NameSpace");
846//        LPOLESTR property_name = property_name_pool;
847//        VARIANTARG varg[1];
848//        DISPPARAMS params;
849//
850//        BSTR bstr_destdir_name;
851//
852//        result = ie->lpVtbl->GetIDsOfNames(ie_Document_Application, &IID_NULL, &property_name, 1, GetUserDefaultLCID(), &dispid);
853//        if (FAILED(result)) {
854//            return;
855//        }
856//
857//        bstr_destdir_name = SysAllocString(destdir_name);
858//        if (bstr_destdir_name == NULL) {
859//            return;
860//        }
861//
862//        VariantInit(&varg[0]);
863//        varg[0].vt = VT_BSTR;
864//        varg[0].bstrVal = bstr_destdir_name;
865//
866//        params.cArgs = 1;
867//        params.cNamedArgs = 0;
868//        params.rgdispidNamedArgs = 0;
869//        params.rgvarg = varg;
870//
871//        result = ie->lpVtbl->Invoke(ie_Document_Application, dispid, &IID_NULL, GetUserDefaultLCID(), DISPATCH_METHOD, &params, &invoke_result, NULL, NULL);
872//
873//        SysFreeString(bstr_destdir_name);
874//
875//        if (FAILED(result)) {
876//            return;
877//        }
878//
879//        ie_Document_Application_NameSpace = invoke_result.pdispVal;
880//    }
881//
882//    // ---------------------------------------------
883//    // ie.Document.Folder
884//    // ---------------------------------------------
885//    {
886//        DISPPARAMS params = {NULL,NULL,0,0};
887//        OLECHAR property_name_pool[] = OLESTR("Folder");
888//        LPOLESTR property_name = property_name_pool;
889//
890//        result = ie->lpVtbl->GetIDsOfNames(ie_Document, &IID_NULL, &property_name, 1, GetUserDefaultLCID(), &dispid);
891//        if (FAILED(result)) {
892//            return;
893//        }
894//
895//        result = ie->lpVtbl->Invoke(ie_Document, dispid, &IID_NULL, GetUserDefaultLCID(), DISPATCH_PROPERTYGET, &params, &invoke_result, NULL, NULL);
896//        if (FAILED(result)) {
897//            return;
898//        }
899//
900//        ie_Document_Folder = invoke_result.pdispVal;
901//    }
902//
903//    // ---------------------------------------------
904//    // ie.Document.Folder.Items()
905//    // ---------------------------------------------
906//    {
907//        DISPPARAMS params = {NULL,NULL,0,0};
908//        OLECHAR property_name_pool[] = OLESTR("Items");
909//        LPOLESTR property_name = property_name_pool;
910//
911//        result = ie->lpVtbl->GetIDsOfNames(ie_Document_Folder, &IID_NULL, &property_name, 1, GetUserDefaultLCID(), &dispid);
912//        if (FAILED(result)) {
913//            return;
914//        }
915//
916//        result = ie->lpVtbl->Invoke(ie_Document_Folder, dispid, &IID_NULL, GetUserDefaultLCID(), DISPATCH_METHOD, &params, &invoke_result, NULL, NULL);
917//        if (FAILED(result)) {
918//            return;
919//        }
920//
921//        ie_Document_Folder_Items = invoke_result.pdispVal;
922//    }
923//
924//    // ---------------------------------------------
925//    // ie.Document.Application.NameSpace("c:\\destination_dir\\").CopyHere ie.Document.Folder.Items()
926//    // ---------------------------------------------   
927//    {
928//        OLECHAR property_name_pool[] = OLESTR("CopyHere");
929//        LPOLESTR property_name = property_name_pool;
930//        VARIANTARG varg[1];
931//        DISPPARAMS params;
932//
933//        result = ie->lpVtbl->GetIDsOfNames(ie_Document_Application_NameSpace, &IID_NULL, &property_name, 1, GetUserDefaultLCID(), &dispid);
934//        if (FAILED(result)) {
935//            return;
936//        }
937//
938//        VariantInit(&varg[0]);
939//        varg[0].vt = VT_DISPATCH;
940//        varg[0].pdispVal = ie_Document_Folder_Items;
941//
942//        params.cArgs = 1;
943//        params.cNamedArgs = 0;
944//        params.rgdispidNamedArgs = 0;
945//        params.rgvarg = varg;
946//
947//        result = ie->lpVtbl->Invoke(ie_Document_Application_NameSpace, dispid, &IID_NULL, GetUserDefaultLCID(), DISPATCH_METHOD, &params, &invoke_result, NULL, NULL);
948//        if (FAILED(result)) {
949//            return;
950//        }
951//    }
952//}
953#else
954void ziptest(void) {
955}
956#endif
957
958/*
959
960#define AU_BUFFER_CREATED_SIGN 108
961
962typedef struct {
963    char created_sign;
964    char* begin;
965    char* end;
966    size_t size;
967} AU_Buffer;
968int AU_CreateBuffer(AU_Buffer** buffer);
969int AU_AppendBuffer(AU_Buffer* buffer, const char* data, size_t size);
970int AU_ReleaseBuffer(AU_Buffer* buffer);
971
972
973int AU_CreateBuffer(AU_Buffer** buffer) {
974    if (!buffer) {
975        return 1;
976    }
977    *buffer = malloc(sizeof(**buffer));
978    if (!*buffer) {
979        return 1;
980    }
981    (*buffer)->created_sign = AU_BUFFER_CREATED_SIGN;
982    (*buffer)->size = 1000;
983    (*buffer)->begin = calloc((*buffer)->size + sizeof(TCHAR), 1);
984    (*buffer)->end = (*buffer)->begin;
985    return 0;
986}
987
988typedef int au_uintptr_t;
989
990int AU_AppendBuffer(AU_Buffer* buffer, const char* data, size_t size) {
991    if (!buffer || buffer->created_sign != AU_BUFFER_CREATED_SIGN) {
992        return 1;
993    }
994    if (!data || size == 0) {
995        return 1;
996    }
997    {
998        size_t total_require = 0;
999        size_t buffer_used = 0;
1000        ptrdiff_t buffer_used_ = (buffer->end - buffer->begin);
1001        if (buffer_used_ < 0) {
1002            return 1;
1003        }
1004        buffer_used = buffer_used_;
1005
1006        total_require = size + buffer_used;
1007        if (total_require < size || total_require < buffer_used) {
1008            // integer overflow
1009            return 1;
1010        }
1011        if (buffer->size < total_require) {
1012            // determine new size
1013            size_t new_size = buffer->size;
1014            char* tmp = NULL;
1015
1016            do {
1017                size_t s = new_size * 2;
1018                if (s < new_size) {
1019                    // integer overflow
1020                    return 1;
1021                }
1022                new_size = s;
1023            } while (new_size < total_require);
1024
1025            tmp = calloc(new_size + sizeof(TCHAR), 1);
1026            if (!tmp) {
1027                return 1;
1028            }
1029            memcpy(tmp, buffer->begin, buffer_used);
1030
1031            free(buffer->begin);
1032            buffer->begin = tmp;
1033            buffer->end = buffer->begin + buffer_used;
1034            if (buffer->end - buffer->begin < 0) {
1035                return 1;
1036            }
1037            buffer->size = new_size;
1038           
1039        }
1040        memcpy(buffer->end, data, size);
1041        buffer->end += size;
1042    }
1043    return 0;
1044}
1045int AU_ReleaseBuffer(AU_Buffer* buffer) {
1046    if (!buffer || buffer->created_sign != AU_BUFFER_CREATED_SIGN) {
1047        return 1;
1048    }
1049
1050    free(buffer->begin);
1051    memset(buffer, 0, sizeof(*buffer));
1052    buffer->created_sign = !AU_BUFFER_CREATED_SIGN;
1053
1054    free(buffer);
1055    return 0;
1056}
1057
1058
1059
1060char* get_random_data(size_t bytes) {
1061    size_t i = 0;
1062    char* data = (char*)malloc(bytes);
1063    if (!data) {
1064        assert(data);
1065        return NULL;
1066    }
1067    srand(time(NULL));
1068    for (i = 0; i < bytes; i++) {
1069        data[i] = (char)((255.0 * (double)rand() / (double)RAND_MAX) - 128);
1070    }
1071    return data;
1072}
1073
1074void buffer_test() {
1075    assert(AU_CreateBuffer(NULL));
1076    {
1077        AU_Buffer b;
1078        AU_Buffer* buffer;
1079        const char data[] = {'t','e','s','t','d','a','t','a'};
1080        const char data2[] = {'t','e','s','t','d','a','t','a','t','e','s','t','d','a','t','a','t','e','s','t','d','a','t','a'};
1081
1082        memset(&b, 0, sizeof(b));
1083        assert(AU_CreateBuffer(&buffer) == 0);
1084        assert(AU_ReleaseBuffer(buffer) == 0);
1085        assert(AU_CreateBuffer(&buffer) == 0);
1086        assert(AU_AppendBuffer(buffer, data, sizeof(data)) == 0);
1087        assert(memcmp(data, buffer->begin, sizeof(data)) == 0);
1088        assert(AU_AppendBuffer(buffer, data, sizeof(data)) == 0);
1089        assert(AU_AppendBuffer(buffer, NULL, sizeof(data)));
1090        assert(AU_AppendBuffer(&b, data, sizeof(data)));
1091        assert(AU_AppendBuffer(buffer, data, (size_t)-1));
1092        assert(AU_AppendBuffer(buffer, data, sizeof(data)) == 0);
1093        assert(AU_AppendBuffer(buffer, data, (size_t)-3));
1094        assert(memcmp(data2, buffer->begin, sizeof(data2)) == 0);
1095        assert(AU_AppendBuffer(&b, data, 0));
1096        assert(AU_ReleaseBuffer(&b));
1097        assert(AU_ReleaseBuffer(buffer) == 0);
1098    }
1099    {
1100        AU_Buffer* buffer;
1101        {
1102            std::string test;
1103            int i = 0;
1104            assert(AU_CreateBuffer(&buffer) == 0);
1105
1106            for (i = 1; i < 50; i++) {
1107                char* data = get_random_data(50 * i);
1108                test.append(data, 50 * i);
1109                assert(AU_AppendBuffer(buffer, data, 50 * i) == 0);
1110                assert(memcmp(test.data(), buffer->begin, test.length()) == 0);
1111                free(data);
1112            }
1113            assert(AU_ReleaseBuffer(buffer) == 0);
1114        }
1115
1116        {
1117            std::string test;
1118            int i = 0;
1119            assert(AU_CreateBuffer(&buffer) == 0);
1120
1121            for (i = 1; i < 10; i++) {
1122                char* data = get_random_data(5000 * i);
1123                test.append(data, 5000 * i);
1124                assert(AU_AppendBuffer(buffer, data, 5000 * i) == 0);
1125                assert(memcmp(test.data(), buffer->begin, test.length()) == 0);
1126                free(data);
1127            }
1128            assert(AU_ReleaseBuffer(buffer) == 0);
1129        }
1130    }
1131}
1132
1133*/
Note: See TracBrowser for help on using the browser.