c++ - salida - ejercicios de archivos en lenguaje c
¿Cómo crear un archivo virtual? (12)
Como no tiene control sobre el DLL, debe suponer que el DLL espera un archivo real. Es probable que en algún momento haga esa suposición, que es la razón por la cual las tuberías con nombre le fallan.
La solución más simple es crear un archivo temporal en el directorio temporal, escribir los datos de su EXE en el archivo temporal y luego eliminar el archivo temporal.
¿Hay alguna razón por la que está integrando este "pseudo archivo" al final de su EXE en lugar de simplemente distribuirlo con nuestra aplicación? Obviamente, ya está distribuyendo esta DLL de terceros con su aplicación, por lo que un archivo más no parece perjudicarlo.
Otra pregunta, ¿esta información estará cambiando? ¿Es así que esperas escribir los datos de este "pseudo-archivo" en tu EXE? No creo que eso funcione bien. Los usuarios estándar pueden no tener acceso de escritura al EXE y eso probablemente generaría tuercas antivirus.
Y definitivamente no funcionarán ningún CreateFileMapping y GetMappedFileName, ya que no le dan un nombre de archivo que se puede pasar a CreateFile. Si de alguna manera pudieras obtener esta DLL para aceptar una HANDLE, entonces eso funcionaría.
Y ni siquiera me molestaría con la intercepción de API. Solo dale a la DLL una ruta a un archivo acutal.
Me gustaría simular un archivo sin escribirlo en el disco. Tengo un archivo al final de mi ejecutable y me gustaría dar su ruta a un dll. Por supuesto, dado que no tiene un camino real, tengo que fingirlo.
Primero intenté usar canalizaciones con nombre en Windows para hacerlo. Eso permitiría un camino como //. / Pipe / mymemoryfile pero no puedo hacer que funcione, y no estoy seguro de que el dll pueda soportar un camino como este.
En segundo lugar, encontré CreateFileMapping y GetMappedFileName. ¿Se pueden usar para simular un archivo en un fragmento de otro? No estoy seguro de que esto sea lo que hace esta API.
Lo que trato de hacer parece similar a la aplicación de cuadros. Alguna idea sobre como lo hacen? Supongo que es algo así como la interceptación API (Like Detour), pero eso sería mucho trabajo. ¿Hay alguna otra forma de hacerlo?
Por qué ? Estoy interesado en esta solución específica porque me gustaría ocultar los datos y para el beneficio de distribuir solo un archivo, pero también por razones geek de hacer que funcione de esa manera;) Estoy de acuerdo en que copiar datos en un archivo temporal funcionaría y ser una solución mucho más fácil.
Las tuberías son para la comunicación entre procesos que se ejecutan simultáneamente. No almacenan datos para un acceso posterior y no tienen la misma semántica que los archivos (por ejemplo, no puede buscar o rebobinar un conducto).
Si buscas un comportamiento similar al de un archivo, la mejor opción será usar un archivo. En Windows, puede pasar FILE_ATTRIBUTE_TEMPORARY
a FILE_ATTRIBUTE_TEMPORARY
como una pista para evitar que se vacíen los datos al disco si hay suficiente memoria.
Si le preocupa el impacto en el rendimiento de escribir en el disco, lo anterior debería ser suficiente para evitar el impacto en el rendimiento en la mayoría de los casos. (Si el sistema tiene suficiente memoria como para forzar la salida de datos del archivo al disco, probablemente también se esté intercambiando de todas formas: ya tiene un problema de rendimiento).
Si intenta evitar escribir en el disco por alguna otra razón, ¿puede explicar por qué? En general, es bastante difícil evitar que los datos penetren en el disco: el usuario siempre puede hibernar la máquina, por ejemplo.
¿Qué le parece usar un tipo de RamDisk y escribir el archivo en este disco? He probado algunos ramdisks, aunque nunca he encontrado uno bueno, dime si tienes éxito.
Bueno, si necesita tener el archivo virtual asignado en su archivo ejecutable, necesitará crear una matriz vector, stream o char lo suficientemente grande como para contener todos los datos virtuales que desea escribir.
esa es la única solución que puedo pensar sin hacer ninguna E / S en el disco (incluso si no escribe en el archivo).
Si necesita conservar un archivo como la sintaxis de la ruta, simplemente escriba una clase que imite ese comportamiento y en lugar de escribir en un archivo, escriba en su búfer de memoria. Es tan simple como se pone. Recuerda KISS.
Aclamaciones
Explique por qué no puede extraer los datos de su EXE y escribirlos en un archivo temporal. Muchas aplicaciones hacen esto: es la solución clásica a este problema.
Si realmente debe proporcionar un "archivo virtual", la solución más limpia probablemente sea un controlador de filtro del sistema de archivos. "limpio" no significa "bueno": un filtro es una solución totalmente documentada y compatible, por lo que es más limpio que API de enganche, inyección, etc. Sin embargo, los filtros del sistema de archivos no son fáciles.
OSR Online es el mejor lugar para encontrar información del sistema de archivos de Windows. La lista de correo NTFSD es donde los desarrolladores del sistema de archivos se juntan .
Leer su pregunta me hizo pensar: si puede pretender que un área de memoria es un archivo y tiene una especie de "ruta virtual", entonces esto permitiría cargar un archivo DLL directamente desde la memoria, que es lo que LoadLibrary
prohíbe por diseño pidiendo un nombre de ruta Y esta es la razón por la cual las personas escriben su propio cargador de PE cuando quieren lograr eso.
Diría que no puede lograr lo que quiere con el mapeo de archivos: el objetivo del mapeo de archivos es tratar una parte de un archivo como si fuera memoria física, y quiere lo recíproco.
Usar Desvíos implica que tendrías que replicar todo lo que hace la función DLL interceptada, excepto obtener datos de un archivo real; por lo tanto, no es genérico. O, incluso más intrincado, imaginemos que el DLL usa fopen
; luego proporcionas tu propio fopen
que detecta un patrón especial en el camino e imitas los elementos internos del tiempo de ejecución de C ... ¿Realmente merece la pena todo el dolor? :RE
Abra el archivo llamado "NUL:" para escribir. Se puede escribir, pero los datos se descartan silenciosamente. Algo así como / dev / null de * nix fama.
Sin embargo, no puedes mapear la memoria. La asignación de memoria implica acceso de lectura / escritura, y NUL es de solo escritura.
Puede almacenar los datos en una secuencia NTFS. De esta forma, puede obtener una ruta real que apunte a sus datos que puede darle a su dll en forma de
x:/myfile.exe:mystreamname
Esto funciona exactamente como un archivo normal, sin embargo, solo funciona si el sistema de archivos utilizado es NTFS. Esto es estándar en Windows hoy en día, pero por supuesto no es una opción si desea admitir sistemas anteriores o si desea poder ejecutarlo desde un dispositivo USB o similar. Tenga en cuenta que cualquier flujo presente en un archivo se perderá si el archivo se envía como un archivo adjunto en el correo o simplemente se copia de una partición NTFS a una partición FAT32.
Yo diría que la forma más compatible sería escribir sus datos en un archivo real, pero por supuesto puede hacerlo de una manera en sistemas NTFS y otro en sistemas FAT. Recomiendo en contra de ello debido a la complejidad añadida. La forma adecuada sería distribuir sus archivos por separado, por supuesto, pero como ha indicado que no desea esto, en ese caso debe escribirlo en un archivo temporal y darle a la DLL la ruta a ese archivo. Asegúrese de escribir el archivo temporal en el directorio temporal de los usuarios (puede encontrar la ruta usando GetTempPath en C / C ++).
Su otra opción sería escribir un controlador de filtro del sistema de archivos, pero ese es un camino que desaconsejo encarecidamente. Ese tipo de derrotas el propósito de usar un solo archivo también ...
Además, en caso de que solo desee un único archivo para la distribución, ¿qué le parece usar un archivo comprimido o un instalador?
¿Has intentado usar el prefijo /? / Cuando usas canalizaciones con nombre? Muchas API admiten el uso de /? / Para pasar el resto de la ruta directamente sin ningún tipo de análisis / modificación.
http://msdn.microsoft.com/en-us/library/aa365247(VS.85,lightweight).aspx
Supongo que esto no puede tomar una secuencia? Es casi fácil de preguntar, PERO si puede, puede usar eso.
¿Por qué no simplemente agregarlo como recurso? Http://msdn.microsoft.com/en-us/library/7k989cfy(VS.80).aspx - de la misma manera que agregaría un ícono.
Use BoxedApp y no se preocupe.