home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / opendc12.zip / od124os2.exe / od12osr1.exe / src / avsshell.cpp < prev    next >
C/C++ Source or Header  |  1997-03-21  |  42KB  |  1,277 lines

  1. /* @(#)Z 1.10 os2/src/avsshell/avsshell.cpp, oddataxfer, od96os2, odos29712d 97/03/21 17:40:37 (97/01/31 11:14:46) */
  2. //====START_GENERATED_PROLOG======================================
  3. //
  4. //
  5. //   COMPONENT_NAME: oddataxfer
  6. //
  7. //   CLASSES: none
  8. //
  9. //   ORIGINS: 82,27
  10. //
  11. //
  12. //   (C) COPYRIGHT International Business Machines Corp. 1995,1996
  13. //   All Rights Reserved
  14. //   Licensed Materials - Property of IBM
  15. //   US Government Users Restricted Rights - Use, duplication or
  16. //   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  17. //       
  18. //   IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  19. //   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  20. //   PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  21. //   CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
  22. //   USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  23. //   OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
  24. //   OR PERFORMANCE OF THIS SOFTWARE.
  25. //
  26. //====END_GENERATED_PROLOG========================================
  27. //
  28.  
  29. //
  30. // Copyright (C) Apple Computer, Inc., 1994
  31. //
  32. //******************************************************************
  33.  
  34. #ifdef _PLATFORM_OS2_
  35.    #include <string.h>
  36.    #include <time.h>
  37.    #define INCL_WIN
  38.    #define INCL_GPI
  39.    #define INCL_BASE
  40.    #define INCL_DOSSEMAPHORES
  41.    #define INCL_DOSERRORS
  42.    #define INCL_WINSTDFILE
  43. // comment out for now. ssl
  44. //   #define INCL_OSAAPI
  45. //   #define INCL_OSA
  46. #endif
  47.  
  48. #include <ISOStr.h>
  49. #include <IODDefs.xh>
  50. #include <ILnkSrvc.xh>
  51. // not found. ssl
  52. //#include <ShSessn.xh>
  53. #include <AvsSessn.xh>
  54. #include <IAvlSvr.xh>
  55. #include <os2.h>
  56. #include <io.h>
  57.  
  58. // 27480
  59. #include <StdTypIO.h>
  60. #include <StdProps.xh>
  61. #include <StdTypes.xh>
  62. #include <TempObj.h>
  63.  
  64. // Just a declaration for ShellMain in os2_feb13\opendoc\src\opendoc\docshell\shlmain.h
  65. // #ifndef _SHLMAIN_
  66. // #include "ShlMain.h"
  67. // #endif
  68.  
  69. #ifndef _AVSSHELL_
  70. #include "AvsShell.h"
  71. #endif
  72.  
  73. #ifndef _ODUTILS_
  74. #include <ODUtils.h>
  75. #endif
  76.  
  77. #ifndef SOM_ODStorageUnit_xh
  78. #include <StorageU.xh>
  79. #endif
  80.  
  81. #ifndef SOM_ODDocument_xh
  82. #include <Document.xh>
  83. #endif
  84.  
  85. #ifndef SOM_ODContainer_xh
  86. #include <ODCtr.xh>
  87. #endif
  88.  
  89. #ifndef SOM_Module_OpenDoc_StdDefs_defined
  90. #include <StdDefs.xh>
  91. #endif
  92.  
  93. #if ODDebug
  94. #ifndef _MEMDEBG_
  95. #include <MemDebg.h>
  96. #endif
  97. #endif
  98.  
  99. #ifndef __STDIO__
  100. #include <stdio.h>
  101. #endif
  102.  
  103. #ifndef _ODDEBUG_
  104. #include "ODDebug.h"  // Adkins -- added (note GetOutput modeis in here now, not Except.h...)
  105. #endif
  106.  
  107. #ifndef _STORUTIL_
  108. #include <StorUtil.h>
  109. #endif
  110.  
  111. #ifdef _PLATFORM_OS2_
  112. // in \opendoc\src\opendoc\docshell in Feb13 build
  113. // #include "debug.h"
  114. #include <odregapi.h>
  115. #include "odtypesf.h"  //119388 @ST
  116. #endif
  117.  
  118. #include <builtin.h>
  119.  
  120. #ifdef _UNICODE_
  121. //************************************
  122. //*   set up for UNICODE             *
  123. //*   8/28/95     jss                *
  124. //************************************
  125.  
  126. #include <unidef.h>
  127. #include <uconv.h>
  128. #include <avuni.h>
  129. #endif
  130. //=============================================================================
  131. // Constants
  132. //=============================================================================
  133.  
  134. #define DONTNEEDSYSTEMPROCESS
  135.  
  136. #ifdef _PLATFORM_OS2_
  137. #define charmacro(a,b,c,d) ((int)a) + ((int)b)*256 + ((int)c)*256*256 + ((int)d)*256*256*256
  138.  
  139. const OSType      kXMPBentoOSType         =  charmacro('b','n','t','o');
  140. const OSType      kXMPQuestionOSType      =  charmacro('?','?','?','?');
  141. const OSType      kXMPAsteriskOSType      =  charmacro('*','*','*','*');
  142. const ODSShort    kOnePageWidth = 600;
  143. const ODError kUnknownDocumentTypeError  =  1001;
  144.  
  145. #endif
  146.  
  147. const ODSShort   kSuspendResumeMessage = 0x01;  // High byte suspend/resume event
  148. const ODSShort   kResumeMask           = 0x01;  // Resume vs. suspend mask
  149.  
  150. const ODSShort    kUseSpecificScript = 0x1c;
  151.  
  152. const  ODSShort  kMaxFileNameSize    = 64;
  153.  
  154.  
  155. // from DrawDef.h
  156. #define kODKindTestDraw "Apple:Kind:TestDraw"
  157.  
  158. // Local error codes:
  159.  
  160. #ifndef kODErrClosingNonODWindow
  161. #define    kODErrClosingNonODWindow  5001
  162. #endif
  163.  
  164. #if ODDebug
  165. const ODMenuID kDebugMenuID = 100;
  166. // Command IDs for the debugging menu:
  167. enum {
  168.   kODCommandDBMemValidation = 980,
  169.   kODCommandDBHeapChecking,
  170.   kODCommandDBLogStdout,
  171.   kODCommandDBLogDebugWindow,
  172.   kODCommandDBSOMTrace
  173. };
  174. #endif
  175.  
  176. //=============================================================================
  177. // Local Macros
  178. //=============================================================================
  179.  
  180. #ifdef ODDebug
  181. #define SHLDebugStr(x)    DebugStr(x)
  182. #else
  183. #define SHLDebugStr(x)
  184. #endif
  185.  
  186. //=============================================================================
  187. // Static variables
  188. //=============================================================================
  189.  
  190. #if ODDebug
  191. static ODBoolean gMemValidation = kODFalse;
  192. static ODBoolean gHeapChecking  = kODFalse;
  193. #endif
  194.  
  195. #ifdef _PLATFORM_OS2_
  196.  
  197. //=============================================================================
  198. // Global Variables
  199. //=============================================================================
  200. HAB hab;        /* anchor block */
  201. HMQ hmq;        /* PM message queue */
  202.  
  203. #ifdef _UNICODE_
  204. //************************************
  205. //*   set up for UNICODE             *
  206. //*   8/28/95     jss                *
  207. //************************************
  208.  
  209. char      szMsg1[CCHMAXPATH];
  210. char      szMsg2[CCHMAXPATH];
  211. #endif
  212.  
  213. //==============================================================================
  214. // Function Prototype
  215. //==============================================================================
  216.  
  217. extern "C" {
  218. MRESULT EXPENTRY ODShellWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  219. }
  220.  
  221. #endif  //_PLATFORM_OS2_
  222.  
  223. ODFileSpec CreateUntitledFileSpec(const char * TheFileName);
  224.  
  225. #ifdef _PLATFORM_OS2_
  226. static ODBoolean isValidBento( FILE *fd );
  227. #endif
  228.  
  229. //=============================================================================
  230. // Static Function
  231. //=============================================================================
  232.  
  233. static void GetCtrDocTopDraft(Environment* ev,
  234.                               ODSession* session,
  235.                               PlatformFile* file,
  236.                               ODContainer** container,
  237.                               ODDocument** document,
  238.                               ODDraft** draft)
  239. {
  240.   ODFileSpec lvalue = file->GetFileSpec();
  241.  
  242.   *container = GetFileContainer(ev, session, &lvalue);
  243.   *document = (*container)->AcquireDocument(ev,kODDefaultDocument);
  244.   *draft = (*document)->AcquireDraft(ev,kODDPReadOnly,0,kODNULL,kODPosTop,kODFalse);
  245. }
  246.  
  247.  
  248. #ifdef _PLATFORM_OS2_
  249.  
  250. char* GetPathName (char* docName)
  251. {
  252.     char   drive[3] = "::";
  253.     char*  hostName;
  254.     char*  pathName;
  255.     APIRET rc = NO_ERROR;
  256.     char*  tmp;
  257.     ULONG  ulOrdinal = 0;
  258.  
  259.     // To eliminate the popup for drive not ready
  260.     // defect 25874
  261.     DosError(FERR_DISABLEHARDERR);
  262.  
  263.     pathName = (char*)SOMMalloc(strlen(docName)+1);
  264.     if (strstr(docName, "LOCALHOST") == docName)
  265.     {
  266.       strcpy(pathName, docName+10);
  267.       return pathName;
  268.     }
  269.  
  270.     if (hostName = getenv("HOSTNAME"))
  271.     {
  272.       if (strstr(docName, strupr(hostName)) == docName)
  273.       {
  274.         strcpy(pathName, docName+strlen(hostName)+1);
  275.         return pathName;
  276.       }
  277.     }
  278.  
  279.     for (char c = 'C'; c <= 'Z'; c++)
  280.     {
  281.       drive[0] = c;
  282.  
  283.       {
  284.         BYTE        fsqBuffer[sizeof(FSQBUFFER2) + (3 * CCHMAXPATH)] = {0};
  285.         PFSQBUFFER2 pfsqBuffer = (PFSQBUFFER2)fsqBuffer;
  286.         ULONG       cbBuffer = sizeof(fsqBuffer);
  287.         PBYTE       prgFSAData = NULL;
  288.         PBYTE       pszFSDName = NULL;
  289.  
  290.         rc = DosQueryFSAttach(drive,
  291.                               ulOrdinal,
  292.                               FSAIL_QUERYNAME,
  293.                               pfsqBuffer,
  294.                               &cbBuffer);
  295.  
  296.         if (rc == NO_ERROR)
  297.         {
  298.           pszFSDName = (BYTE*)(pfsqBuffer->szName + pfsqBuffer->cbName + 1);
  299.           prgFSAData = strupr(pszFSDName + pfsqBuffer->cbFSDName + 1);
  300.  
  301.           // Only consider NFS remote file
  302.           if ((pfsqBuffer->iType == FSAT_REMOTEDRV) &&
  303.               (strcmp(pszFSDName, "NFS") == 0))
  304.           {
  305.             if (strstr(docName, prgFSAData) == docName)
  306.             {
  307.               pathName = (char*)malloc(strlen(docName) + 3);
  308.               pathName[0] = c;
  309.               pathName[1] = ':';
  310.               pathName[2] = '\0';
  311.               strcat(pathName, docName+strlen(prgFSAData));
  312.               return pathName;
  313.             }
  314.           }
  315.         }
  316.       }
  317.     }
  318.  
  319.     // To eliminate the popup for drive not ready
  320.     // defect 25874
  321.     DosError(FERR_ENABLEHARDERR);
  322.  
  323.     // Default is pathName = docName
  324.     strcpy(pathName, docName);
  325.     return pathName;
  326. }
  327. const ULONG kBUFFER_SIZE = 2048;
  328.  
  329. ODBoolean VerifyKind(ODISOStr kind)
  330. {
  331.    char pBuffer[kBUFFER_SIZE];    // 119227
  332.    ULONG size = kBUFFER_SIZE;
  333.    OSErr err = 0;
  334.  
  335.    if(!kind[0]) return kODFalse; // [123673]
  336.    int rc = ODQueryPartHandlerList( kind, pBuffer, (ODULong) &size);
  337.  
  338.    if(!size)
  339.    {
  340.            return kODFalse;   // [123673] : don't throw here !
  341.  
  342. #ifdef _UNICODE_
  343.  
  344.             WinLoadString( WinQueryAnchorBlock(HWND_DESKTOP), NULLHANDLE,
  345.                            AV_PARTREGERROR, sizeof(szMsg1), szMsg1);
  346.  
  347.             WinLoadString( WinQueryAnchorBlock(HWND_DESKTOP), NULLHANDLE,
  348.                            AV_ERRORTITLE, sizeof(szMsg2), szMsg2);
  349.  
  350.             WinMessageBox(HWND_DESKTOP,
  351.                                  HWND_DESKTOP,
  352.                                  szMsg1,
  353.                                  szMsg2,
  354.                                  0L,
  355.                                  MB_OK | MB_CRITICAL);
  356. #else
  357.             WinMessageBox(HWND_DESKTOP,
  358.                                  HWND_DESKTOP,
  359.                                  "Part Registration Information Not Found!",
  360.                                  "Error!",
  361.                                  0L,
  362.                                  MB_OK | MB_CRITICAL);
  363. #endif // _UNICODE_
  364.  
  365.            THROW(err);
  366.    }
  367.  
  368. //   SOMFree(pBuffer);
  369.    return kODTrue;
  370. }
  371. #endif
  372.  
  373. //=============================================================================
  374. // AvsShell
  375. //=============================================================================
  376.  
  377.  
  378. //-----------------------------------------------------------------------------
  379. // Initialization
  380. //-----------------------------------------------------------------------------
  381.  
  382. AvsShell::AvsShell()
  383. {
  384.   fSOMEnvironment     = kODNULL;
  385.   fSession         = kODNULL;
  386.   fContainer         = kODNULL;
  387.   fDocument         = kODNULL;
  388.   fDraft           = kODNULL;
  389.   fSurrogateContainer = kODNULL;
  390.   fSurrogateDocument  = kODNULL;
  391.   fSurrogateDraft     = kODNULL;
  392.   fAvailabilityServer = kODNULL;
  393.   fPermissions      = kODDPNone;
  394.   fPlatformWindow = kODNULL;  // @res
  395.   fDraftIsSaved = kODFalse;
  396. }
  397.  
  398. //-----------------------------------------------------------------------------
  399. //-----------------------------------------------------------------------------
  400.  
  401. AvsShell::~AvsShell()
  402. {
  403.   if (fDraft!=kODNULL)
  404.   {
  405.     ODFinalReleaseObject(fSOMEnvironment,fDraft);
  406.     ODFinalReleaseObject(fSOMEnvironment,fDocument);
  407.     ODFinalReleaseObject(fSOMEnvironment,fContainer);
  408.     ODFinalReleaseObject(fSOMEnvironment,fSurrogateDraft);
  409.     ODFinalReleaseObject(fSOMEnvironment,fSurrogateDocument);
  410.     ODFinalReleaseObject(fSOMEnvironment,fSurrogateContainer);
  411.     ODDisposeHandle(fSurrogateContainerHandle);
  412.   }
  413.  
  414.   delete fAvailabilityServer;
  415.   delete fSession;
  416. }
  417.  
  418. //-----------------------------------------------------------------------------
  419. //-----------------------------------------------------------------------------
  420.  
  421. void AvsShell::Initialize(char* name /* filename of doc and alias of server */)
  422. {
  423.  
  424.   // 1. Get SOM
  425.   // 2. Create a session, using class AsSession (like ShellSession, but talks to me)
  426.   // (deleted) 3. Get system facilities from that session
  427.   // 4. Tell the session how to talk to me.
  428.   // (deleted) 5. Install menus
  429.   // 6. Create surrogate Container, Document, and Draft
  430.   // 7. Create availability server
  431.   // 8. Initialize windows (not in delayed-start version)
  432.  
  433.   // 1.
  434.   fSOMEnvironment = somGetGlobalEnvironment();
  435.   fPermissions = kODDPExclusiveWrite;
  436.  
  437.   // 2.
  438.   fSession = new AVSShellSession;
  439.   fSession->InitAvailServerSession(fSOMEnvironment, name);
  440.  
  441.   // 3.
  442.  
  443.   // 4.
  444.   fSession->SetShellPointer(fSOMEnvironment, this);
  445.  
  446.   // 5.
  447.  
  448.   // 6.
  449.    TRY
  450.       fSurrogateContainerHandle = ODNewHandle(0);
  451.       fSurrogateContainer = CreateMemoryContainer(
  452.                               fSOMEnvironment,
  453.                               fSession,
  454.                               fSurrogateContainerHandle,
  455.                               kODBentoMemoryContainer);
  456.       fSurrogateDocument = fSurrogateContainer->
  457.                              AcquireDocument(fSOMEnvironment,
  458.                                              kODDefaultDocument);
  459.       fSurrogateDraft = fSurrogateDocument->
  460.                           AcquireBaseDraft(fSOMEnvironment, kODDPExclusiveWrite);
  461.    CATCH_ALL
  462.       RERAISE;
  463.    ENDTRY
  464.  
  465.    // 7.
  466.    // the availability server is useless until InitAvailServer is called
  467.    fAvailabilityServer = new IODAvailServer;
  468.  
  469.    // 8.
  470. }
  471.  
  472. //-----------------------------------------------------------------------------
  473. // Main Entry Point
  474. //-----------------------------------------------------------------------------
  475.  
  476. void AvsShell::go( int argc, char *argv[] )
  477. {
  478.     char *    odcfgVariable  = "ODCFG";
  479.     PCSZ      odcfgValue     = 0;
  480.     const     kMaxBufferSize = 1024;
  481.     char *    fileNameIn     = "avlsrvr.bto";
  482.     ODBoolean printing       = kODFalse;                 //  ced [1174742]
  483.     char      completeFileName[kMaxBufferSize];
  484.     char      completeBkpFileName[kMaxBufferSize];
  485.     char      kindName[120];
  486.     char      asName[256];
  487.  
  488.     //check environment where opendoc odcfg directory is ("etc") Note: no trailing '\' or ';'
  489.     if ( !DosScanEnv( odcfgVariable, &odcfgValue) )
  490.     {
  491.       if (odcfgValue)                                         // If ODCFG is set
  492.       {
  493.         strcpy(completeFileName, odcfgValue);                 // Use it as the path
  494.         strcat(completeFileName, "\\");                       // Add a trailing '\'
  495.       }
  496.     }
  497.     // Note that if ODCFG not set or error above, then completeFileName is still empty and we don't use a path.
  498.  
  499.     strcat( completeFileName, fileNameIn);
  500.  
  501.     //create fully qualified name for the backup file
  502.     //replace ".bto" with ".bak"
  503.     strcpy(completeBkpFileName,completeFileName);                // Start with same path, file name, and extension
  504.     completeBkpFileName[strlen(completeBkpFileName)-3] = '\0';   // Remove "bto" extension
  505.     strcat(completeBkpFileName,"bak");                           // Append "bak" extension
  506.  
  507.     char* asSuffixName = getenv("AVLSVRNAME") ? getenv("AVLSVRNAME") : "AS";
  508.     strcpy(asName, getenv("HOSTNAME"));
  509.     strcat(asName, "_");
  510.     strcat(asName, asSuffixName);
  511.  
  512.     TRY
  513.       // this->Initialize();  wait until we've parsed the input
  514.       // hab and hmq needed to be defined here so that subsequent call
  515.       // to WinMessageBox will bring up the message box!
  516.       hab = WinInitialize(0);
  517.       hmq = WinCreateMsgQueue( hab, 0 );
  518.  
  519.       PlatformFile* file = new PlatformFile;
  520.       kindName[0] = 0;
  521.  
  522.       int argnum = 1;
  523.       while (argnum < argc) {
  524.         char * thisarg =  argv[argnum];
  525.         if (thisarg[0]=='-')
  526.         {
  527.           switch (thisarg[1])
  528.           {
  529.             case 'f':
  530.             case 'F':
  531.               if (strlen(thisarg+2) > 0) fileNameIn = thisarg+2;
  532.               break;
  533.           } /* endswitch */
  534.         }
  535.         else if (thisarg[0]==0)
  536.              {
  537.                  // weird! specified an empty string.  Ignore
  538.              }
  539.              else
  540.              {
  541.                 // Do nothing here:
  542.                 // AvsShell.exe ignore other arguments other that -f -t -s
  543.              } /* endif */
  544.         argnum++;
  545.       } /* endwhile */
  546.  
  547.       ODBoolean existsFile;
  548.       if ( fileNameIn)
  549.       {
  550.         {
  551.           // Presumed nonexistant until proven otherwise
  552.           existsFile = kODFalse;
  553.           FILE *fp = fopen(completeFileName, "rb "); //(129464)
  554.           if ( fp )
  555.           {
  556.             // fileNameIn exists, but possibly invalid
  557.             existsFile = kODTrue;
  558.  
  559.             if (!isValidBento( fp ) )
  560.             {
  561.               // Close completeFileName since it's an invalid bento file
  562.               fclose(fp);
  563.  
  564.               // Open the backup bento file
  565.               fp = fopen(completeBkpFileName, "rb");
  566.  
  567.               // Check if backup bento file is valid
  568.               if (fp && isValidBento(fp))
  569.               {
  570.                 // Copy the backup bento file to completeFileName
  571.                 APIRET rc = DosCopy(completeBkpFileName, completeFileName, DCPY_EXISTING);
  572.                 if (rc != NO_ERROR)
  573.                 {
  574.  
  575.                   // DosCopy returns an error
  576.  
  577. #ifdef _UNICODE_
  578. //************************************
  579. //*   set up for UNICODE             *
  580. //*   8/28/95     jss                *
  581. //************************************
  582.  
  583.                   WinLoadString( WinQueryAnchorBlock(HWND_DESKTOP), NULLHANDLE,
  584.                                  AV_CANTRESTOREBTO, sizeof(szMsg1), szMsg1);
  585.  
  586.                   WinLoadString( WinQueryAnchorBlock(HWND_DESKTOP), NULLHANDLE,
  587.                                  AV_ERRORTITLE, sizeof(szMsg2), szMsg2);
  588.  
  589.                   WinMessageBox(HWND_DESKTOP,
  590.                                 HWND_DESKTOP,
  591.                                 szMsg1,
  592.                                 szMsg2,
  593.                                 0L,
  594.                                 MB_OK | MB_ERROR);
  595. #else
  596. /*
  597.                   WinMessageBox(HWND_DESKTOP,
  598.                                 HWND_DESKTOP,
  599.                                 "Cannot restore avlsrvr.bto!",
  600.                                 "Error!",
  601.                                 0L,
  602.                                 MB_OK | MB_ERROR);
  603. */
  604.                     fclose(fp);
  605.                     DosDelete(completeBkpFileName);
  606.                     DosDelete(completeFileName);
  607.                     existsFile = kODFalse;
  608.  
  609. #endif
  610. //                  return;
  611.                 }
  612.                 else
  613.                 {
  614.                   // DosCopy ok
  615.                   fclose(fp);
  616.                 }
  617.               }
  618.               else
  619.               {
  620.                 // Backup bento file does not exist or is invalid
  621.  
  622. #ifdef _UNICODE_
  623. //************************************
  624. //*   set up for UNICODE             *
  625. //*   8/28/95     jss                *
  626. //************************************
  627.  
  628.                 WinLoadString( WinQueryAnchorBlock(HWND_DESKTOP), NULLHANDLE,
  629.                                AV_BTOBAKCORRUPT, sizeof(szMsg1), szMsg1);
  630.  
  631.                 WinLoadString( WinQueryAnchorBlock(HWND_DESKTOP), NULLHANDLE,
  632.                                AV_ERRORTITLE, sizeof(szMsg2), szMsg2);
  633.  
  634.                 WinMessageBox(HWND_DESKTOP,
  635.                               HWND_DESKTOP,
  636.                               szMsg1,
  637.                               szMsg2,
  638.                               0L,
  639.                               MB_OK | MB_ERROR);
  640. #else
  641. /*
  642.                 WinMessageBox(HWND_DESKTOP,
  643.                               HWND_DESKTOP,
  644.                               "Avlsrvr.bto and Avlsrvr.bak are both corrupted!\nDelete them and restart AVSSHELL.EXE",
  645.                               "Error!",
  646.                               0L,
  647.                               MB_OK | MB_ERROR);
  648. */
  649.  
  650.                   fclose(fp);
  651.                   DosDelete(completeBkpFileName);
  652.                   DosDelete(completeFileName);
  653.                   existsFile = kODFalse;
  654. #endif
  655. //                return ;
  656.               } //endif
  657.             }
  658.             else
  659.             {
  660.               // Back up the bento file for avsshell
  661.               APIRET rc = DosCopy(completeFileName, completeBkpFileName, DCPY_EXISTING);
  662.               fclose(fp);
  663.             } /* endif */
  664.           } /* endif */
  665.         }
  666.       } /* endif */
  667.  
  668.       if (completeFileName && existsFile)        //(129464)
  669.       {
  670.         ODFileSpec fileSpec;
  671.         strcpy((char*)(fileSpec.name), completeFileName); //129464)
  672.         this->Initialize(fileNameIn);
  673.         file->Specify( &fileSpec );
  674.         this->OpenFile( file);
  675.         this->Open();
  676.         fSession->StartServer(fSOMEnvironment, asName);
  677.         this->OpenDraft(fDraft);
  678.       }
  679.       else
  680.       {
  681.         // this is the normal startup when
  682.         // the AS is started for the first time from an empty file
  683.         ODFileSpec fileSpec;
  684.         char * fileNameUsed = completeFileName;  //129464
  685.  
  686.         this->Initialize(fileNameUsed);
  687.         file = this->OpenUntitled( fileNameUsed );
  688.         this->Open();
  689.         fSession->StartServer(fSOMEnvironment, asName);
  690.         this->OpenDraft(fDraft);
  691.       } /* endif */
  692.  
  693.     CATCH_ALL
  694.       DebugStr("ODShell: Initialize() failed");
  695.       return;
  696.     ENDTRY
  697.  
  698.       QMSG qmsg;                           /* Message from message queue   */
  699.       if (!printing) {                      // ced [117472]
  700.         while( WinGetMsg( hab, &qmsg, 0L, 0, 0 ) )
  701.           WinDispatchMsg( hab, &qmsg );
  702.         if (!fDraftIsSaved) this->SaveDraft();
  703.       }
  704.       ODReleaseObject(fSOMEnvironment,fDraft);
  705.       ODReleaseObject(fSOMEnvironment,fDocument);
  706.       ODReleaseObject(fSOMEnvironment,fContainer);
  707.  
  708.       WinDestroyMsgQueue( hmq );           /* Tidy up...                   */
  709.       WinTerminate( hab );                 /* Terminate the application    */
  710. }
  711.  
  712. //-----------------------------------------------------------------------------
  713. //-----------------------------------------------------------------------------
  714.  
  715. MRESULT EXPENTRY ODShellWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  716. {
  717.    switch (msg) {
  718.      case WM_PAINT:
  719.      {
  720.        RECTL rcl;
  721.        HPS hps = WinBeginPaint(hwnd, NULLHANDLE, &rcl);
  722.        WinFillRect(hps, &rcl, CLR_WHITE);
  723.        WinEndPaint(hps);
  724.        return 0;
  725.      }
  726.  
  727.      case WM_CLOSE:
  728.      {
  729.        AvsShell* theShell = (AvsShell *)WinQueryWindowPtr(hwnd, 0);
  730.        theShell->SaveDraft();
  731.        WinPostQueueMsg( hmq, WM_QUIT, 0, 0);
  732.        break;
  733.      }
  734.    }
  735.    return WinDefWindowProc(hwnd, msg, mp1, mp2);
  736. }
  737.  
  738. //-----------------------------------------------------------------------------
  739. //-----------------------------------------------------------------------------
  740.  
  741. int QueryFilePath( ODFileSpec fspec)
  742. {
  743.    FILESTATUS3 fs3;
  744.    APIRET err;
  745.    err = DosQueryPathInfo( (PSZ)fspec.name
  746.                                     , /*infolevel:std*/ FIL_STANDARD
  747.                                     , &fs3
  748.                                     , sizeof(fs3)
  749.                                     );
  750.    return err;  // if an error occurs, then let's assume we're supposed
  751.                  // to say the file doesn't exist
  752. }
  753.  
  754. //-----------------------------------------------------------------------------
  755. //-----------------------------------------------------------------------------
  756.  
  757. ODFileSpec  AvsShell::CreateNamedContainer(ODDocument** documentPtr,
  758.                                            ODContainer** containerPtr,
  759.                                            PlatformFile* currentFile,
  760.                                            const char * basename)
  761. {
  762.    PlatformFile*    file;
  763.    HMTX             hmtx;
  764.  
  765.    //<crs>-11/15/94-protect file creation with a mutex sem.
  766.  
  767. #ifdef _UNICODE_
  768. //************************************
  769. //*   set up for UNICODE             *
  770. //*   8/28/95     jss                *
  771. //************************************
  772.  
  773.    WinLoadString( WinQueryAnchorBlock(HWND_DESKTOP), NULLHANDLE,
  774.                   AV_SEMUNTITLED, sizeof(szMsg1), szMsg1);
  775.  
  776.    APIRET rc = DosCreateMutexSem( szMsg1, &hmtx,
  777.                         DC_SEM_SHARED, 0 );
  778. #else
  779.    APIRET rc = DosCreateMutexSem( "\\SEM32\\UNTITLED", &hmtx,
  780.                         DC_SEM_SHARED, 0 );
  781. #endif
  782.  
  783.  
  784.    if ( rc == ERROR_DUPLICATE_NAME )
  785. #ifdef _UNICODE_
  786.       rc = DosOpenMutexSem( szMsg1, &hmtx );
  787. #else
  788.       rc = DosOpenMutexSem( "\\SEM32\\UNTITLED", &hmtx );
  789. #endif
  790.  
  791. #ifdef _UNICODE_
  792.    WinLoadString( WinQueryAnchorBlock(HWND_DESKTOP), NULLHANDLE,
  793.                   AV_CANNOTOPENSEM, sizeof(szMsg1), szMsg1);
  794.    WinLoadString( WinQueryAnchorBlock(HWND_DESKTOP), NULLHANDLE,
  795.                   AV_CANNOTGETSEM, sizeof(szMsg2), szMsg2);
  796.  
  797.    WASSERTM( rc == NO_ERROR, szMsg1 );
  798.  
  799.    rc = DosRequestMutexSem( hmtx, SEM_INDEFINITE_WAIT );
  800.    WASSERTM( rc == NO_ERROR, szMsg2 );
  801. #else
  802. //   WASSERTM( rc == NO_ERROR, "Can't open 'Untitled' sempahore" );
  803.  
  804.    rc = DosRequestMutexSem( hmtx, SEM_INDEFINITE_WAIT );
  805. //   WASSERTM( rc == NO_ERROR, "Can't get 'Untitled' sempahore" );
  806. #endif
  807.    ODFileSpec myTSpec = currentFile->GetFileSpec();
  808.    file = new PlatformFile();
  809.  
  810.    strcpy( (char*)(myTSpec.name), basename);
  811.  
  812.    file->Specify(&myTSpec);
  813.    file->Create(kODShellSignature, kODShellSignature, 0);
  814.  
  815.   (*containerPtr) = CreateFileContainer(fSOMEnvironment, fSession, &myTSpec );
  816.   if (documentPtr)
  817.     (*documentPtr) = (*containerPtr)->AcquireDocument(fSOMEnvironment,kODDefaultDocument);
  818.  
  819.    //<crs>-12/06/94-Let the workplace know it is an OpenDoc file.
  820. //   file->Open();
  821.  
  822. #ifdef _UNICODE_
  823. //************************************
  824. //*   set up for UNICODE             *
  825. //*   8/28/95     jss                *
  826. //************************************
  827.  
  828.    WinLoadString( WinQueryAnchorBlock(HWND_DESKTOP), NULLHANDLE,
  829.                   AV_OPENDOCDOCUMENT, sizeof(szMsg1), szMsg1);
  830.    file->SetEAFromName( ".TYPE", szMsg1 );
  831. #else
  832. //   file->SetEAFromName( ".TYPE", "OpenDoc Document" );
  833. #endif
  834. //    file->Close();
  835.  
  836.    rc = DosReleaseMutexSem( hmtx );
  837.    rc = DosCloseMutexSem( hmtx );
  838.  
  839.    return myTSpec;
  840. }
  841.  
  842. //-----------------------------------------------------------------------------
  843. // Open
  844. //-----------------------------------------------------------------------------
  845.  
  846. void  AvsShell::OpenFile(PlatformFile*  file)
  847. {
  848. // Comments added: /******** strom@watson ********/
  849. // This function is called if a file already exists.
  850. // The job of this function is to obtain the top draft
  851. // of the document represented by this file.
  852. // The side effect is to initialize fContainer, fDocument, fDraft,
  853. // and fIsNew.
  854.  
  855.   GetCtrDocTopDraft(fSOMEnvironment,
  856.                     fSession,
  857.                     file,
  858.                     &fContainer,
  859.                     &fDocument,
  860.                     &fDraft);
  861.   fDraft = fDocument->AcquireDraft(fSOMEnvironment,
  862.                                    fPermissions,
  863.                                    0,
  864.                                    fDraft,
  865.                                    kODPosSame,
  866.                                    kODTrue);
  867.   fIsNew = kODFalse;   /******** strom@watson ********/
  868. }
  869.  
  870. //-----------------------------------------------------------------------------
  871. //-----------------------------------------------------------------------------
  872.  
  873. PlatformFile* AvsShell::OpenUntitled(const char *FileName)
  874. {
  875.   // Comments added: /******** strom@watson ********/
  876.   // create a container, get the draft and set the DraftProperties
  877.   // Despite its name, OpenUntitled creates a new Document file, regardless of
  878.   // whether it is untitled or not.
  879.   // A side effect is to initialize fDocument, fContainer, fDraft, and fIsNew
  880.   // An invisible side effect is to initialize fDraft's DraftProperties
  881.   // to include editor kind and editor name.  These properties will be
  882.   // readable later by Open.
  883.  
  884.   // res: In the memory-streamlined version, these properties will be
  885.   // ignored later by Open.
  886.  
  887.   PlatformFile* currentFile = new PlatformFile;
  888.  
  889.   ODFileSpec newFileFSP = CreateNamedContainer(&fDocument,
  890.                                                &fContainer,
  891.                                                currentFile,
  892.                                                FileName);
  893.   currentFile->Specify( &newFileFSP);
  894.  
  895.   fDraft = fDocument->AcquireBaseDraft(fSOMEnvironment, fPermissions);
  896.   ODStorageUnit* su = fDraft->AcquireDraftProperties(fSOMEnvironment);
  897.   fDraft->Externalize(fSOMEnvironment);
  898.   ODReleaseObject(fSOMEnvironment, su );
  899.  
  900.   fIsNew = kODTrue;
  901.  
  902.   return ( currentFile );
  903. }
  904.  
  905. //-----------------------------------------------------------------------------
  906. // The following comments are from /******** strom@watson ********/
  907.  
  908. // Open is called after the last saved draft has been loaded or
  909. // a new draft has been created.
  910.  
  911. // The function of Open is:
  912. // 1. to establish the visible draft:
  913. //   if the document is read-only, the visible draft is the current draft.
  914. //   if the document is read-write, a new draft should be created
  915. //      on top of the current draft, and this becomes the visible draft.
  916. //      Also the LinkService should be opened.
  917. //
  918. // 2. to bring up the root part, either by
  919. // creating it if it hasn't yet been created, or by asking the
  920. // draft to internalize it if it has already been created.
  921. // res: In the streamlined version, we do not bring up any
  922. // root part.  Instead, we merely create a platform window
  923. // (which the root part would have done) We don't create
  924. // an ODWindow from this platform window, nor do we store it
  925. // in the session, or save its open state in the draft or
  926. // any of those things that normal documents do.
  927. //
  928. // In the delayed-start version, we defer this step until
  929. // window-initialization ("OpenDraft") time
  930.  
  931. // 3. to perform whatever window management is required by the platform.
  932. //    res: In the streamlined version, we just do a WinShowWindow
  933. //         on the platform window to make it visible.  We don't
  934. //         in particular use any objects of class WindowState.
  935. //         And in the delayed-start version, we defer this step
  936. //         until window-initialization ("OpenDraft") time
  937. //-----------------------------------------------------------------------------
  938.  
  939. void  AvsShell::Open()
  940. {
  941.   if (fDraft==kODNULL) return;
  942.  
  943.   if (this->HasWriteAccess()) {
  944.     fDraft = fDocument->CreateDraft(fSOMEnvironment,fDraft,kODTrue);
  945.  
  946.     /******** strom@watson ********/
  947.     ODFileSpec documentFile = GetPlatformFileFromContainer(
  948.                                 fSOMEnvironment, fContainer)->GetFileSpec();
  949.   }
  950.  
  951.  
  952.   // Comments added by // strom@watson
  953.   // In the previous implementation, the true branch never
  954.   // executed for brand new files because the functionality
  955.   // was duplicated in OpenUntitled.  Now this code will
  956.   // execute for new files, creating the root part.
  957.  
  958.  
  959.   fAvailabilityServer->InitAvailServer(fSOMEnvironment,
  960.                                        fIsNew,
  961.                                        this,
  962.                                        fDraft,
  963.                                        fSurrogateDraft);
  964. }
  965.  
  966. //-----------------------------------------------------------------------------
  967. // this doesn't get called in the streamlined version
  968. // but it does get called in the delayed-start version
  969. //
  970. // internalize the windowstate and open windows of fDraft
  971. // In the delayed-start version, all the window-related stuff
  972. // goes here.  Delayed-start is only used with streamlined;
  973. // therefore there is no ODWindow object, only PM Windows:
  974. // The steps are as follows:
  975. // 1. Initialize the PM Window system
  976. //    Since the DSOM server is already running, this can no longer
  977. //    deadlock with a docshell process which is trying to
  978. //    auto-start the avsshell while handling a PM event.
  979. // 2. Register a PM class
  980. // 3. Create a platform window
  981. // 4. show the platform window on the screen
  982. //-----------------------------------------------------------------------------
  983.  
  984. void  AvsShell::OpenDraft(ODDraft* draft)
  985. {
  986. //---<1>
  987.      hab = WinInitialize(0);
  988.      hmq = WinCreateMsgQueue( hab, 0 );
  989.  
  990. //---<2>
  991.      WinRegisterClass(                /* Register window class        */
  992.         hab,                          /* Anchor block handle          */
  993.         (PSZ)"OpenDocShell",          /* Window class name            */
  994.         (PFNWP)ODShellWndProc,        /* Address of window procedure  */
  995.         CS_SIZEREDRAW,                /* Class style                  */
  996.         4);                           /* Extra window words           */
  997.                                       /* 119471 [pfe] */
  998. //---<3>
  999.     fPlatformWindow = fSession->CreatePlatformWindow(fSOMEnvironment, ODPlatformWindowDefaultCreateOptions);
  1000.  
  1001. //---<4>
  1002.    WinShowWindow(fPlatformWindow, FALSE);
  1003. }
  1004.  
  1005. //-----------------------------------------------------------------------------
  1006. //-----------------------------------------------------------------------------
  1007.  
  1008. void AvsShell::SaveDraft()
  1009. {
  1010.   // externalize the draft
  1011.   if ( this->HasWriteAccess() && fDraft->ChangedFromPrev(fSOMEnvironment) )
  1012.   {
  1013.     fDraft->Externalize(fSOMEnvironment);
  1014.     fDraftIsSaved = kODTrue;
  1015.   }
  1016. }
  1017.  
  1018. //-----------------------------------------------------------------------------
  1019. // Drafts
  1020. //-----------------------------------------------------------------------------
  1021.  
  1022. ODBoolean  AvsShell::HasWriteAccess()
  1023. {
  1024. // returns whether draft was open w/ write access
  1025.   return fPermissions>=kODDPSharedWrite;
  1026. }
  1027.  
  1028. //-----------------------------------------------------------------------------
  1029. // Availability Server access
  1030. //-----------------------------------------------------------------------------
  1031.   // CloneLinkSource:
  1032.   // Called by availability server when a linkID needs to be opened.
  1033.   // The pathName is used to find the document.  The
  1034.   // document is opened read-only.  The linkservice is
  1035.   // asked to find the SU of the LinkSource corresponding to this linkID.
  1036.   // This LinkSource is then cloned into the surrogateDraft,
  1037.   // and the SUID of that clone is returned.
  1038.  
  1039. ODStorageUnitID AvsShell::CloneLinkSource(ODLinkID linkID,
  1040.                                            ODISOStr docName)
  1041. {
  1042. // 1. Open up a temporary container, document, and (R/O) draft for the file in pathName
  1043. // 2. Call LinkManager::GetLinkSrcInDraft to find this linkID in this draft
  1044. // 3. Clone the linksource from the temporary draft to the surrogate draft
  1045. // 4. Release the temporary container, document, and draft
  1046.  
  1047. // 1.
  1048.   PlatformFile* tempFile = new PlatformFile;
  1049.   ODFileSpec tempFileSpec;
  1050.   ODContainer* tempContainer = kODNULL;
  1051.   ODDocument* tempDocument = kODNULL;
  1052.   ODDraft* tempDraft = kODNULL;
  1053.   ODStorageUnitID lsSUID;
  1054.   ODStorageUnitID clonedLsSUID;
  1055.   ODDraftKey key;
  1056.  
  1057.   //tempFileSpec.name = kODNULL;
  1058.   TRY
  1059.  
  1060.     char* pathName = GetPathName(docName);
  1061.     if (_access(pathName, 00) == -1)
  1062.     {
  1063.       SOMFree(pathName);
  1064.       THROW(kODErrInvalidDocPathName);
  1065.     }
  1066.  
  1067.     strcpy((char*)(tempFileSpec.name), pathName);
  1068.     SOMFree(pathName);
  1069.  
  1070.     tempFile->Specify(&tempFileSpec);
  1071.     GetCtrDocTopDraft(fSOMEnvironment,
  1072.                       fSession,
  1073.                       tempFile,
  1074.                       &tempContainer,
  1075.                       &tempDocument,
  1076.                       &tempDraft);
  1077.  
  1078.  
  1079.   // 2.
  1080.   lsSUID = fSession->
  1081.              GetLinkService(fSOMEnvironment)->
  1082.                GetLinkSrcInDraft(fSOMEnvironment, tempDraft, linkID);
  1083.  
  1084.   // 3.
  1085.   key = tempDraft->BeginClone(fSOMEnvironment, fSurrogateDraft, kODNULL, kODCloneAll);
  1086.   clonedLsSUID = tempDraft->Clone(fSOMEnvironment, key, lsSUID, 0, 0);
  1087.  
  1088.   // 27480
  1089.   // Use GetWeakSURefProp and SetWeakSURefProp to obtain values.
  1090.   {
  1091.      TempODStorageUnit tempSU = tempDraft->AcquireStorageUnit(fSOMEnvironment, lsSUID);
  1092.      ODID partID = ODGetWeakSURefProp (fSOMEnvironment, tempSU,
  1093.                          kODPropSourcePart, kODWeakStorageUnitRef);
  1094.      if (partID) {
  1095.         ODID newID = tempDraft->Clone(fSOMEnvironment, key, partID, kODNULL, kODNULL);
  1096.         TempODStorageUnit tempNewSU = fSurrogateDraft->AcquireStorageUnit(fSOMEnvironment, clonedLsSUID);
  1097.         ODSetWeakSURefProp (fSOMEnvironment, tempNewSU,
  1098.                      kODPropSourcePart, kODWeakStorageUnitRef, newID);
  1099.      }    /* endif */
  1100.      else
  1101.      PRINT("******** Error no part ID\n");
  1102.   }
  1103.   tempDraft->EndClone(fSOMEnvironment, key);
  1104.  
  1105.   // 4.
  1106.   if (tempDraft != kODNULL)
  1107.   {
  1108.     ODReleaseObject(fSOMEnvironment,tempDraft);
  1109.     ODReleaseObject(fSOMEnvironment,tempDocument);
  1110.     ODReleaseObject(fSOMEnvironment,tempContainer);
  1111.   }
  1112.   delete tempFile;
  1113.   //if (tempFileSpec.name != kODNULL) delete tempFileSpec.name;
  1114.   return(clonedLsSUID);
  1115.  
  1116.   CATCH_ALL
  1117.     if (tempDraft != kODNULL)
  1118.     {
  1119.       ODReleaseObject(fSOMEnvironment,tempDraft);
  1120.       ODReleaseObject(fSOMEnvironment,tempDocument);
  1121.       ODReleaseObject(fSOMEnvironment,tempContainer);
  1122.     }
  1123.     delete tempFile;
  1124.  
  1125.     RERAISE;
  1126.     return(0);
  1127.  
  1128.   ENDTRY
  1129.  
  1130. }
  1131.  
  1132. /*
  1133.  *=============================================================================
  1134.  *=============================================================================
  1135.  */
  1136.  
  1137. void AvsShell::SetDocListHWND(HWND docListHWND)
  1138. {
  1139.   fDocListHWND = docListHWND;
  1140. }
  1141.  
  1142. /*
  1143.  *=============================================================================
  1144.  *=============================================================================
  1145.  */
  1146.  
  1147. void AvsShell::UpdateDocList(ULONG docID,
  1148.                             char* pathName,
  1149.                             char flag)
  1150. {
  1151.     char item[512];
  1152.     time_t ltime;
  1153.     char stime[26];
  1154.  
  1155.     if (!getenv("AVSSHELL_UPDATE"))
  1156.       return;
  1157.  
  1158.     time(<ime);
  1159.     sprintf(stime, ctime(<ime));
  1160.     stime[24] = '\0';
  1161.     memset(item, 0, 512);
  1162.  
  1163.     switch(flag)
  1164.     {
  1165.       case 'o':
  1166.         sprintf(item, "DocID [%d] named [%s] is opened on [%s]", docID, pathName, stime);
  1167.         break;
  1168.       case 'c':
  1169.         sprintf(item, "DocID [%d] named [%s] is closed on [%s]", docID, pathName, stime);
  1170.         break;
  1171.       case 'r':
  1172.         sprintf(item, "DocID [%d] named [%s] is removed on [%s]", docID, pathName, stime);
  1173.         break;
  1174.     }
  1175.  
  1176.     HMQ tmpq = WinCreateMsgQueue(hab, 0);
  1177.     if (tmpq != NULLHANDLE)
  1178.     {
  1179.       WinSendMsg(fDocListHWND,
  1180.                  LM_INSERTITEM,
  1181.                  MPFROMSHORT(LIT_END),
  1182.                  MPFROMP(item));
  1183.       WinDestroyMsgQueue(tmpq);
  1184.     }
  1185. }
  1186.  
  1187. /*
  1188.  *=============================================================================
  1189.  *=============================================================================
  1190.  */
  1191.  
  1192. void AvsShell::SetLinkListHWND(HWND linkListHWND)
  1193. {
  1194.   fLinkListHWND = linkListHWND;
  1195. }
  1196.  
  1197. /*
  1198.  *=============================================================================
  1199.  *=============================================================================
  1200.  */
  1201.  
  1202. void AvsShell::UpdateLinkList(ULONG linkID,
  1203.                              ULONG docID,
  1204.                              ULONG flag)
  1205. {
  1206.     char item[512];
  1207.     time_t ltime;
  1208.     char stime[26];
  1209.  
  1210.     if (!getenv("AVSSHELL_UPDATE"))
  1211.       return;
  1212.  
  1213.     time(<ime);
  1214.     sprintf(stime, ctime(<ime));
  1215.     stime[24] = '\0';
  1216.     memset(item, 0, 512);
  1217.  
  1218.     switch(flag)
  1219.     {
  1220.       case 0:
  1221.         sprintf(item, "LinkID [%d] of DocID [%d] resides on file on [%s]", linkID, docID, stime);
  1222.         break;
  1223.       case 1:
  1224.         sprintf(item, "LinkID [%d] of DocID [%d] resides in document on [%s]", linkID, docID, stime);
  1225.         break;
  1226.       case 2:
  1227.         sprintf(item, "LinkID [%d] of DocID [%d] resides in Link Manager on [%s]", linkID, docID, stime);
  1228.         break;
  1229.       case 3:
  1230.         sprintf(item, "LinkID [%d] of DocID [%d] resides in both document and Link Manager on [%s]", linkID, docID, stime);
  1231.         break;
  1232.       case 4:
  1233.         sprintf(item, "LinkID [%d] of DocID [%d] is removed on [%s]", linkID, docID, stime);
  1234.         break;
  1235.     }
  1236.  
  1237.     HMQ tmpq = WinCreateMsgQueue(hab, 0);
  1238.     if (tmpq != NULLHANDLE)
  1239.     {
  1240.       WinSendMsg(fLinkListHWND,
  1241.                  LM_INSERTITEM,
  1242.                  MPFROMSHORT(LIT_END),
  1243.                  MPFROMP(item));
  1244.       WinDestroyMsgQueue(tmpq);
  1245.     }
  1246. }
  1247.  
  1248.  
  1249. #define LBLmagicBytes      0  /* 8 bytes: the magic byte identifier          */
  1250. #define LBLflags          8   /* 2        the label flags                    */
  1251. #define LBLbufSize       10   /* 2        TOC buffer size / 1024            */
  1252. #define LBLmajorVersion   12  /* 2        major format version number        */
  1253. #define LBLminorVersion   14  /* 2        minor format version number        */
  1254. #define LBLtocOffset     16   /* 4        offset to start of TOC            */
  1255. #define LBLtocSize       20   /* 4        total byte size of the TOC        */
  1256.  
  1257. #define LBLsize           24  /* defined size of the container label        */
  1258.  
  1259. #define MagicByteSequence "\xA4""CM""\xA5""Hdr""\xD7"    /* Must be 8 characters          */
  1260.  
  1261. static ODBoolean isValidBento( FILE *fp )
  1262. {
  1263.    long pos;
  1264.    unsigned char label[LBLsize];
  1265.    ODBoolean validFile = kODFalse;
  1266.  
  1267.    fseek( fp, 0L, SEEK_END );
  1268.    pos = ftell( fp ) - sizeof( label );
  1269.    if (!fseek( fp, pos, SEEK_SET ))
  1270.       if ( fread( &label, 1, sizeof( label ), fp ) == sizeof( label ))
  1271.          if ( !( memcmp( &label, MagicByteSequence,
  1272.                                strlen( MagicByteSequence ) )))
  1273.             validFile = kODTrue;
  1274.  
  1275.    return( validFile );
  1276. }
  1277.