CodeHard

Artículos computacionales

ene 22, 18:40
Hola

Wordpress es un gestor de blogs muy completo: posee un detallado sistema de estadísticas, un amigable editor WYSIWYG, un buen gestor de comentarios, dialogos para thumbnails y videos, un sistema de tags, una extensa lista de plugins y temas y muchas opciones de configuración.

TextPattern no tiene ninguna de las ventajas anteriores. Es un sistema sencillo, su editor (llamado Textile) es bastante complejo, no tiene un sistema de estadísticas, es difícil encontrar plugins y themes además de ser un sistema bastante manual.

¿Por qué uso TextPattern? En realidad ni yo sé, me lo recomendaron una vez por ser seguro y ligero, y como quería probar otra cosa que no sea Wordpress, decidí usarlo. ¿Recomiendo TextPattern? Depende a quién.

TextPattern no te servirá si quieres hacer dinero en Internet, o si quieres tener infinidad de dialogos, efectos y funciones. Aunque obviamente puede ser modificado y mejorado a gusto, es una opción que no tiene sentido habiendo otros gestores. De igual manera, es muy ligero y veloz, por lo cual si las modificaciones no son muchas vale la pena.

Por empezar, TextPattern tiene algunos trucos para ser optimizado. Debemos tener en claro que la gran mayoría de las cosas se guardan en la base de datos SQL, incluyendo las hojas de estilo CSS. Realmente desconozco el motivo por el cual es guardada allí, supongo que será para poder editarla desde la misma aplicación o para que no quede a la vista, aunque no guarda mucho sentido. Para añadir la hoja de estilo a la página por medio de TextPattern, hay que usar el tag <txp: css>, aunque la mayoría (entre ellos yo) recomienda añadirla estáticamente ya que cargará mucho más rápido y ahorraremos peticiones a SQL. También hay un plugin llamado rvm_css que es prácticamente lo mismo, solo que simula que está en la base de datos lo que nos permite editarla desde la aplicación.

También he desactivado estas opciones desde las preferencias avanzadas que no sirven para mucho:

  • lastmod_keepalive
  • Actualizar en ping-o-matic.com
  • ¿Ping textpattern.com?

Otra de las cosas que definitivamente a la mayoría no le gusta, es el uso de Textile. Si me preguntas, prefiero escribir directamente en HTML: es muy complicado, no tiene muchas opciones y hubo veces que tuve que malgastar varios minutos en solucionar problemas de carácteres y demás. En fin, a los que sufren lo mismo que yo, les recomiendo que añadan el plugin hak_tinymce que añade un editor WYSIWYG.

La administración de imágenes es bastante básica. Es decir, simplemente la subimos y luego las imprimimos mediante el tag image y el thumbnail. Quizás algunos prefieran Wordpress, que si bien es mucho más facil e intuitivo, podemos estar horas cargando la imágen, y nuestro navegador puede ser comido por lo pesados efectos flash y ajax. Yo odio esperar, por lo cual prefiero hacerlo manualmente. El único problema con el que me encontré, fue con la creación de thumbnails, ya que crea la imágen según el tamaño que especifiquemos, lo cual no entiendo, ¿que sentido tiene este método si nos queda una imágen sin relación entre el alto y el ancho? ¿no es mejor subir nuestra propia miniatura? De igual manera, lo solucioné haciendole algunas modificaciones al archivo txp_image dentro de la carpeta textpattern/include
function thumbnail_create()
    {
       
        extract(doSlash(gpsa(array('id', 'width', 'height'))));
        global $txpcfg,$img_dir;
       
        extract($txpcfg);
        $id = assert_int(ps('id'));
        // better checking of thumbnail dimensions
        // don't try and use zeros
        $rs = safe_row('*', 'txp_image', "id = $id");

        if ($rs) {
            extract($rs);
        $width = (int) $width;
        $height = (int) $height;
       
        list($w, $h) = getimagesize(IMPATH.'/'.$id.$ext);
       
        $w = (int) $w;
        $h = (int) $h;

       
        if ($width == 0 && $height == 0) {
            image_edit(messenger('invalid_width_or_height', "($width)/($height)", ''), $id);
            return;
        } else {
            if ($width == 0) {
                $width = '';
            }

            if ($height == 0) {
                $height = '';
            }
        }

        $crop = gps('crop');

        $t = new txp_thumb( $id );
        $t->crop = ($crop == '1');
        $t->hint = '0';

        $t->width = $width / 100 * $w;
        $t->height = $height / 100 * $h;

        if ($t->write())
        {
            global $prefs;

            $prefs['thumb_w'] = $width;
            $prefs['thumb_h'] = $height;
            $prefs['thumb_crop'] = $crop;

            // hidden prefs
            set_pref('thumb_w', $width, 'image',    2);
            set_pref('thumb_h', $height, 'image',     2);
            set_pref('thumb_crop', $crop, 'image',    2);

            $message = gTxt('thumbnail_saved', array('{id}' => $id));
            update_lastmod();

            image_edit($message, $id);
        }

        else
        {
            $message = gTxt('thumbnail_not_saved', array('{id}' => $id));

            image_edit($message, $id);
        }
        }
    }
Ahora las dimensiones que le pasemos al thumbnail no será el alto ni el ancho final, si no que será el porcentaje del tamaño de la imágen original. Por ejemplo si queremos reducir la imágen a la mitad, solo ponemos las dos dimensiones en 50. Si bien no es tan elegante, funciona y es lo que importa.

Con eso ya les andará bastante mejor. Yo por lo menos no tengo mucho más de que quejarme, y anda bastante rápido en comparación a otros sitios. Así que espèro que a alguno le halla servido :P


Salu2
No hay comentarios
dic 9, 18:51

Hola

Parecido al artículo Detrás del SpywareBlaster… está vez voy a hablar de un programa bastante conocido llamado ERUNT, utilidad para realizar backups del registro de Windows. A diferencia del sistema de copias de seguridad del regedit, este programa guarda de forma binaria todo el registro de Windows .

La idea de este artículo comenzó debido a mi intención de añadir una función similar ofrecida en este programa a mi aplicación RegUnlocker, de modo tal de ofrecer un sistema de backups más veloz y completo, además de ser mucho más útil a la hora de errores de sistema.

En un principio debo reconocer que no tuve suerte al deducir como funcionaba la aplicación. Sinceramente siempre pensé que copiaba los archivos de la propia copia de seguridad de Windows, (C:\WINDOWS\repair) lo que no explicaría el lento proceso necesario para su copia, o que se las ingeniaba para copiar directamente los archivos de sistema de Windows de la carpeta C:\WINDOWS\System32, lo que era totalmente descabellado, ya que requeriría un método tipo DLL Injection lo que no va con este tipo de aplicaciones. Pero, ¿por qué llegue a pensar tal funcionamiento? Todo se debió a que ERUNT crea un backup de las entradas del registro más importantes, y las nombra exactamente igual a su equivalente en Windows, es decir a los siguientes archivos:

  • DEFAULT
  • SAM
  • SECURITY
  • SOFTWARE
  • SYSTEM
  • NTUSER.DAT (uno por cada cuenta de usuario)

Luego, observando detenidamente los archivos creados, es fácil darse cuenta que no son iguales a los originales de Windows, lo que nos dice que esos archivos realmente salen de otro lado. Después de buscar en Google largo rato, no log´re encontrar ninguna solución concreta, así que procedí a fijarme que hace realmente la aplicación:

Lo que podemos ver en esa imagen es que la aplicación lo que hace es obtener el provilegio de acceso SeBackupName. Si investigan un poco en el msdn, podrán averiguar que este privilegio sirve para acceder a entradas del registro y archivos protegidos en modo de solo lectura, para poder ejecutar algunas funciones de backup. Además se hace una llamada a la función RegCreateKeyEx, que no solo sirve para crear claves en el registro, si no para obtener el HANDLE de la clave, (manipulador) de manera muy similar a la que trabaja la función CreateFile, la cual está destinada a archivos y directorios. Ahora, ¿por qué usa esa función en vez de RegOpenKey o RegCreateKey?

Para que vean más de cerca, en este caso se obtiene el HANDLE de la clave HKEY_LOCAL_MACHINE\SYSTEM”, pero si prestan atención verán que el valor del parámetro Options es REG_OPTION_BACKUP_RESTORE. Este flag es muy importante durante el proceso si se desea tener total acceso de lectura al registro, lo cual es necesario para realizar el backup.

Por último, aquí es donde viene la parte más interesante para mí, donde aparece una función que desconocía de la api Win32:

Seguro les va a ser necesario agrandar la imagen, pero podrán observar que en el momento de hacerse una llamada a una función llamada RegSaveKeyEx, el programa Filemon detecta la creación del archivo de backup. ¡Bingo! Por fin encontramos la función que guarda el registro al estilo ERUNT :)

Ahora veamos como podemos hacer los pasos anteriores programaticamente. Para eso utilizaremos C++ y la directiva windows.h. En primer lugar lo que hacemos es obtener los privilegios SeBackupName. Para eso obtenemos el HANDLE de nuestro proceso, luego creamos una estructura TOKEN_PRIVILEGES con el flag SE_BACKUP_NAME, la añadimos a nuestro proceso, y por último liberamos todos los HANDLES que utilizamos:

BOOL GetPrivileges() //Get SeBackup Privileges
{
BOOL bReturn = FALSE;
HANDLE hToken;
TOKEN_PRIVILEGES NewPrivileges;

if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken))
{
CloseHandle(hToken); return(FALSE);
}

if(LookupPrivilegeValue(0, SE_BACKUP_NAME, &NewPrivileges.Privileges[0].Luid)) {

NewPrivileges.PrivilegeCount = 1; NewPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED
}
else { CloseHandle(hToken); return FALSE; }

bReturn = AdjustTokenPrivileges(hToken, FALSE, &NewPrivileges, 0 ,0 ,0); CloseHandle(hToken);
return bReturn;
}

Creamos una función la cual reciba la entrada del registro a guardar y luego un nombre de archivo de salida y nos haga el backup automáticamente:

BOOL GetRegistryKey(HKEY RootKey, LPCSTR SubKey, LPCSTR FileName)
{ long lRval; HKEY hKey;

DWORD Result;

Result = RegCreateKeyEx(RootKey, SubKey, 0, NULL, REG_OPTION_BACKUP_RESTORE, 0, NULL, &hKey, NULL);

if (Result!=ERROR_SUCCESS) { cout << “Couldn’t Open Registry Key” << endl; GetErrorMessage(Result); RegCloseKey(hKey); return FALSE; }

Result = RegSaveKey(hKey, FileName, 0); if (Result!=ERROR_SUCCESS) { cout << “Couldn’t save Registry Key” << endl; GetErrorMessage(Result); RegCloseKey(hKey); return FALSE; }

RegCloseKey(hKey); return TRUE;
}

Por último, teniendo ya estas dos funciones, lo único que hacemos es elegir que claves o subclaves queremos guardar, un juego de niños. Aquí les muestro un ejemplo de una función main:

#include <cstdlib>

#include <iostream>

#include <windows.h>

using namespace std;

BOOL GetPrivileges();
BOOL GetRegistryKey(HKEY RootKey, LPCSTR SubKey, LPCSTR FileName);
void GetErrorMessage(DWORD err);

int main(int argc, char *argv[])
{ if (GetPrivileges()==TRUE) { cout << “Privileges got succesfully”<< endl; } else { return 1; }

if(GetRegistryKey(HKEY_LOCAL_MACHINE, “SAM”, “SAM”)==TRUE) { cout << “Sam backuped succesfully”<< endl; }

if(GetRegistryKey(HKEY_LOCAL_MACHINE, “SECURITY”, “Security” )==TRUE) { cout << “Security backuped succesfully”<< endl; }

if(GetRegistryKey(HKEY_LOCAL_MACHINE, “SOFTWARE”, “Software”)==TRUE) { cout << “Software backuped succesfully”<< endl; }

if(GetRegistryKey(HKEY_LOCAL_MACHINE, “SYSTEM”, “System”)==TRUE) { cout << “System backuped succesfully”<< endl; }

cout << “Finished” <<endl;
system(“PAUSE”);
return EXIT_SUCCESS;
}



void GetErrorMessage(DWORD err)
{
TCHAR msg[256];

FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, msg, 255, NULL);
cout << msg << endl;;
}

Conclusiones

Como ven no es nada difícil crear copias de seguridad mediante este método más allá de las ventajas que conlleva como la velocidad de creación y el tamaño de la copia. El único inconveniente es que la información se guarda en una especia de formato cifrado o binario por lo cual es imposible su edición, lo que lo vuelve inutilizable para ciertas tareas.

Saludos

No hay comentarios

Búsqueda

Anuncios

Donación

CodeHard por Mauro Ezequiel Soria
Licenciado bajo Creative Commons