"Memory could not be Read/Written" crashes with C extension DLL... HELP PLEASE!

Kevin Cazabon kevin at cazabon.com
Sat Apr 6 01:23:55 EST 2002


I've gotten past many hurdles so far, but I can't seem to figure out
what's causing my problems.  The DLL I've built works just fine...
unless you call pyHasp (see below) multiple times (random.. sometimes
it works fine for 40 calls, sometimes it works for 300 calls, then
crashes).

The error is one of two:  'Instruction at xxxxxx referenced memory at
xxxxx.  The memory could not be "written"' or could not be "read"...
random which one it gives.

I've tried debugging, but it seems the actual violation is in
NTDLL.DLL, I'm assuming I'm causing it somehow...

Can ANYONE look at the funciton below and let me know if I am doing
something wrong, probably in the area of retaining a reference to a
PyObject, or using the wrong pointer somewhere...  ANY suggestions are
welcome, I've tried almost everything.  I've also tried commenting out
sections one at a time (the memcpy sections, the CallHasp section, and
the AsReadBuffer/AsWriteBuffer sections) to see if it gets rid of the
problem, but it hasn't helped...???

Thanks!

Kevin.

///////////////////////////////////////////////////////////////
static PyObject *
pyHasp(PyObject *self, PyObject *args)
{
  // declarations
  PyObject *pReturn = NULL;

  PyObject *pLong1 = NULL;
  PyObject *pLong2 = NULL;
  PyObject *pLong3 = NULL;
  PyObject *inBuffer = NULL;
  int inBufferSize = 0;

  char *pInBufferAsReadBuffer = NULL;
  char *pInBufferAsWriteBuffer = NULL;

  ULONG Service = 0;
  ULONG SeedCode = 0;
  ULONG LptNum = 0;
  ULONG Pass1 = 0;
  ULONG Pass2 = 0;

  ULONG p1 = 0;
  ULONG pp1 = 0;
  ULONG p2 = 0;
  ULONG p3 = 0;
  ULONG pp3 = 0;

  char *EncodeDecodeBuffer = NULL;
  ULONG pUL_EncodeDecodeBuffer = 0;

  // parse the PyObject arguments, assign to variables accordingly
  // inBuffer is a Python 'B' array, which supports the buffer
interface
  if (!PyArg_ParseTuple(args, "llllllllOl", &Service, &SeedCode,
&LptNum, &Pass1, &Pass2, &p1, &p2, &p3, &inBuffer, &inBufferSize)) {
    return Py_BuildValue("llls", -9999, -9999, -9999, "Could not parse
the Python Tuple!");
  }

  // Check the size of the inBuffer for validity
  if (inBufferSize > 1000) {
    return Py_BuildValue("llls", -9998, -9998, -9998, "Encode / Decode
buffer must be less than 1000 characters.");
  }

  if (inBufferSize < 8) {
    return Py_BuildValue("llls", -9997, -9997, -9997, "Encode / Decode
buffer must be 8 characters or more in length.");
  }

  // allocate the memory for the EncodeDecodeBuffer
  EncodeDecodeBuffer = malloc(inBufferSize);
  if (!EncodeDecodeBuffer) {
    return Py_BuildValue("llls", -9994, -9994, -9994, "Could not
allocate memory for the EncodeDecodeBuffer!");
  }
  memset (EncodeDecodeBuffer, 0, inBufferSize);

  // Obtain a pointer to the Python Buffer Interface for inBuffer
(readable)
  if (PyObject_CheckReadBuffer(inBuffer)) {
    if ((Service != 1) && (Service != 5)) {
      if (PyObject_AsReadBuffer(inBuffer, &pInBufferAsReadBuffer,
&inBufferSize) == -1) { // PyObject_AsReadBuffer is fucked up in its
return values... -1 is error, 0 is success
        return Py_BuildValue("llls", -9995, -9995, -9995, "Could not
access the passed string as a Python buffer!");
      }
    }
  } 
  else {
      return Py_BuildValue("llls", -9995, -9995, -9995, "inBuffer does
not support Buffer Interface!");
  } 

  // the Python values should NOT be modified in place, make copies to
pass to hasp function
  pp1 = p1;
  pp3 = p3;

  // copy the inBuffer to the EncodeDecodeBuffer, use memcpy so that
nulls don't cause problems
  if  ((Service != 1) && (Service != 5)) {
    memcpy(EncodeDecodeBuffer, pInBufferAsReadBuffer, (unsigned
int)inBufferSize);
  }

  // get a ULONG pointer to EncodeDecodeBuffer
  pUL_EncodeDecodeBuffer = (ULONG) EncodeDecodeBuffer;

  // send the data to the hasp driver for encoding/decoding/whatever
  // this function modifies pp1, inBufferSize, pp3, EncodeDecodeBuffer
(through the pUL_ pointer) in place
  CallHasp(Service, SeedCode, LptNum, Pass1, Pass2, &pp1,
&inBufferSize, &pp3, &pUL_EncodeDecodeBuffer);

  // copy the EncodeDecodeBuffer back to the inBuffer, through a
pointer to the Python Buffer interface (writable)
  if  ((Service != 1) && (Service != 5)) {
    if (PyObject_AsWriteBuffer(inBuffer, &pInBufferAsWriteBuffer,
&inBufferSize) == -1) {
      return Py_BuildValue("llls", -9994, -9994, -9994,
"PyObject_AsWriteBuffer Failed!");
    }
    memcpy(pInBufferAsWriteBuffer, EncodeDecodeBuffer, (unsigned
int)inBufferSize);
  }

  free(EncodeDecodeBuffer);


  // build pp1, inBufferSize, pp3 into PyObjects for returning
  pLong1 = PyLong_FromLong(pp1);
  pLong2 = PyLong_FromLong(inBufferSize);
  pLong3 = PyLong_FromLong(pp3);

  // build pLong1, pLong2, pLong3, pString into a tuple to return

  pReturn = PyTuple_New(4);
  PyTuple_SetItem(pReturn, 0, pLong1); 
  PyTuple_SetItem(pReturn, 1, pLong2);
  PyTuple_SetItem(pReturn, 2, pLong3);
  PyTuple_SetItem(pReturn, 3, inBuffer);

  return pReturn;
}



More information about the Python-list mailing list