This is the mail archive of the cygwin-developers mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Avoid collisions between parallel installations of Cygwin


cgf wrote:
> So, while it might be neat to put these in the resource section, isn't
> that normally ASCII data?  Or is it binary too?  It's been too long
> since I played with that.

No, you can store binary data in a resource section using RCDATA. It's a
bit tricky to store streams of bytes (other than strings), but it can be
done. And WORDs or DWORDs are easy, although you have to worry about
alignment when switching between data types (the entire RCDATA resource
will be DWORD aligned to start with).

windres -o foo_res.o -i foo_res.rc
gcc -o foo.o -c foo.c
gcc -o foo.exe foo.o foo_res.o
./foo.exe

If we add the discussed functionality and make it an option, it makes
sense to me to do it using resources ('course we'd need to provide a
(native win32) user tool to manipulate it). That way, it can be
interpreted by cygwin exactly once on load with no additional disk
access, and there's no question about changing (say /bin/.cygwinrc)
while the DLL is loaded and wondering why it hasn't taken effect -- in
this case, while the DLL is loaded you can't modify it.

And...by changing the DLL, you change its checksum so we could easily
distinguish a modified DLL from the real distributed ones, even without
the manipulation tool. Just compare md5sums.

It seems to me that this sort of thing is very different from the type
of stuff we use the CYGWIN variable for...

--
Chuck

X bitmap

#include <stdlib.h>
#include <stdio.h>
#include <windows.h>

#define CYGPROPS_RES_NAME "cygprops"

#define CYGPROPS_STRUCT_VERSION 0x00000001
typedef struct _cygprops {
  unsigned short allow_multiple;
  unsigned short something_else;
  unsigned short extra_sz; /* size of byte array, below */
  unsigned char *extra;    /* must be even; extend to extra_sz+1 if needed */
} cygprops_t;

cygprops_t cygprops = { 0, 0, 0, NULL };

void * readres_ushort(void *addr, unsigned short *val)
{
  unsigned short * p = (unsigned short *) addr;
  *val = *p++;
  return (void *) p;
}
void * readres_uchars_bswap(void *addr, unsigned int cnt, unsigned char *val)
{
  unsigned char * p = (unsigned char *) addr;
  unsigned char a,b;
  int i;
  for (i = 0; i < cnt; )
    {
      a = *p++;
      b = *p++;
      i += 2;
      *val++ = b;
      *val++ = a;
    }
  return (void *) p;
}

void load_props(void)
{
  int i;
  LPVOID lpcygprops;
  unsigned short cygprops_version;

  // Load toolbar resource.
  HMODULE hMod = GetModuleHandle(NULL);
  HGLOBAL hglb = LoadResource(hMod, FindResource(hMod, CYGPROPS_RES_NAME, RT_RCDATA));
  lpcygprops = LockResource(hglb);
  lpcygprops = readres_ushort(lpcygprops, &cygprops_version);
  if (cygprops_version != CYGPROPS_STRUCT_VERSION)
    {
      fprintf(stderr, "bad cygprops version; expected %d got %d\n",
              CYGPROPS_STRUCT_VERSION, cygprops_version);
      exit (1);
    }

  lpcygprops = readres_ushort(lpcygprops, &cygprops.allow_multiple);
  lpcygprops = readres_ushort(lpcygprops, &cygprops.something_else);
  lpcygprops = readres_ushort(lpcygprops, &cygprops.extra_sz);
  cygprops.extra = (unsigned char *) malloc (cygprops.extra_sz & 0x01
                                             ? cygprops.extra_sz + 1
                                             : cygprops.extra_sz);
  lpcygprops = readres_uchars_bswap(lpcygprops, cygprops.extra_sz, cygprops.extra);

  UnlockResource (hglb);
  FreeResource (hglb);
}
void destroy_props(void)
{
  if (cygprops.extra)
    {
      free(cygprops.extra);
      cygprops.extra = NULL;
    }
}
void print_cygprops(void)
{
  int i;
  unsigned char *p;
  printf("allow_multiple: 0x%04x\n", cygprops.allow_multiple);
  printf("something_else: 0x%04x\n", cygprops.something_else);
  printf("extra_sz      : 0x%04x\n", cygprops.extra_sz);
  printf("extra         :");
  if (cygprops.extra)
    {
      for (i = 0, p = cygprops.extra; i < cygprops.extra_sz; i++)
          printf(" 0x%02x", *p++);
      printf("\n");
    }
  else
    printf(" <NULL>\n");
}

int main(int argc, char *argv[])
{
  printf("BEFORE: \n");
  print_cygprops();
  printf("AFTER: \n");
  load_props();
  print_cygprops();
  destroy_props();
  return 0;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]